【问题标题】:Why is there no function in standard C library like realloc() without data copying?为什么没有数据复制的标准 C 库中没有像 realloc() 这样的函数?
【发布时间】:2011-10-05 11:27:18
【问题描述】:

比如我想要这样一个功能:

char *dst = (char*)malloc(512);
char *src = (char*)malloc(1024);
...
dst = (char*)realloc(dst, 1024);
memcpy(dst, src, 1024);

如你所见,我只是想让函数 realloc() 扩展缓冲区的大小,但 C 库中的 realloc() 可能会从旧地址复制数据。那么任何库中是否有我想要的功能?

【问题讨论】:

  • 如果您不关心旧内容,为什么不直接free/malloc 缓冲区?
  • 不要转换malloc()的返回值。它充其量是多余的,并且可能隐藏编译器在没有它时会发现的错误。
  • 遗憾的是,在用 C++ 编写 C-esk 代码时,您必须强制转换它。我敢打赌这就是正在发生的事情。
  • 我明白为什么不能可靠地扩展内存。但是可靠地缩小分配呢?例如,我过度分配了一个内存池,当程序达到稳态时,我将池重新分配到更小的大小。
  • @Mat:减少内存碎片是原因之一。

标签: c memory realloc


【解决方案1】:

为什么不只是:

free(dst);
dst = malloc(1024);

还请注意realloc 可能会移动块并调整其大小,因此持有由先前调用malloccallocrealloc 返回的旧指针可能不再引用同一块。

【讨论】:

  • @tristopia: realloc 在重新分配失败时不会丢失旧指针。相反,在覆盖旧指针之前不检查失败的损坏的调用代码是可能导致它丢失的原因。
【解决方案2】:

realloc 尝试在不复制的情况下扩展缓冲区,但只有在额外空间可用时才能这样做。

在您的情况下,您刚刚为src 分配了空间,而该内存块可能已经使用了realloc 需要的空间。在这种情况下,它只能在其他地方分配一个更大的块并将数据复制到该块。

【讨论】:

  • 谢谢。是的,你是对的。实际上我的意思是......使用带有 flag=HEAP_REALLOC_IN_PLACE_ONLY 的 HeapReAlloc() 来尝试扩展缓冲区大小,如果失败,只需分配一个新块而不复制数据。你知道 HeapReAlloc() 是 OS API,我不想处理堆。所以我想也许应该有一个像我想要的 C 库中的函数。
【解决方案3】:

那么任何库中是否有我想要的功能?

不,没有。如果没有空间,系统应该如何扩展内存?

例如想象你这样做:

char *a = malloc(2);
char *b = malloc(2);

分配的内存现在可能如下所示:

1 2 3 4 5 6 7 ------------------------- | | | | | | | ------------------------- \ /\ /\ / \ / \ / \ / v v v 未使用的内存/内存 对于“a”内部对于“b” 记忆片

现在你做 realloc(a,10); 。系统不能简单地将内存块扩展为“a”。它会命中“b”使用的内存,因此它必须在内存中找到另一个有 10 个连续空闲字节的位置,从旧内存块复制 2 个字节并返回一个指向这些新 10 个字节的指针.

【讨论】:

  • 是的,你是对的,所以经常进行“移动”操作。但是我想让系统做的是“如果你不能扩展一块a,就分配一个新的一块,但不要复制数据,我不需要它”。
  • @legendlee 这样的东西在标准C中是不存在的。如果你反正不关心数据,就不能用malloc()吗?
  • @nos 您首先需要一个 free,然后是一个 malloc。虽然使用此假设操作,但您将首先尝试在可能的情况下扩展分配的内存而不释放它,这可能更有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
  • 2014-06-28
  • 1970-01-01
  • 2012-04-05
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多