2

我目前正在尝试为队列数据结构设计一个公共 API,并调整函数以更改其大小。我的第一个意图是通过以下方式做到这一点:

typedef struct queue queue;

/**
 * Resizes a given queue.
 *
 * Changes the size of the queue passed as a parameter. 
 * The content of the resized queue prior to the lesser
 * of new and old sizes is left unchanged. 
 *
 * Returns:
 *  0 - on success
 * -1 - on error and the content of the original queue is left unchanged
 */
int queue_resize(queue * queue_ptr, size_t new_size);

问题是我阅读了合同,realloc内容如下:

realloc函数返回一个指向新对象的指针(它可能与指向旧对象的指针具有相同的值),如果无法分配新对象,则返回一个空指针。

重新分配函数返回一个新对象并回收旧对象是一种常见的方法吗?因此,在这种情况下,我应该重新设计int queue_resize(queue *queue_ptr, size_t);以进行queue * queue_resize(queue *queue_ptr, size_t);相应的合同更改。

4

2 回答 2

3

realloc必须能够将分配的空间移动到不同的地址才能工作。想象一下当前分配的内存已经在使用之后的内存。如果没有重定位,您将无法创建连续的序列。

通常你的队列看起来像这样

typedef struct queue {
  some_type* data_member;
  size_t size;
  size_t capacity;
  // .. perhaps more
} queue;

所以当你有一个queue_resize函数时,你可以只传递 aqueue*和新的大小。你传递给realloc的不是 thequeue*而是它的data_member. 由于您已经有一个指向该queue对象的指针,您只需更新data_memberifrealloc选择更改它的指针。

queue*在这种情况下,不需要返回一个新对象,因为内存占用queue永远不会改变。你也不必通过aqueue**或任何类似的东西。

于 2019-04-20T10:32:43.600 回答
2

以前的答案/评论没有说明如何处理数据。当 Java 运行时发现 Array 需要更大时,请考虑在 Java 中做了什么。例如,您尝试将元素附加到已经完整的数组中。

  • 分配了一个具有所需大小的新数组;这包括设置元数据
  • 必须设置一个锁,这样旧的数组就不会改变
  • 所有数据都从现有数组复制到新数组;包括更新元数据;请注意,这两个数组需要同时存在
  • 原始 Array 被删除(不确定这里的正确词。)
  • 锁被移除
  • 如果您只是摆弄指针,您将丢失数据。
  • 您可以使用 Add() 和 Remove() 等标准方法轻松复制数据
于 2019-04-20T11:50:06.690 回答