标准C库中为什么没有像realloc()那样不需要复制数据的函数?

8
例如,我想要这样一个函数:
char *dst = (char*)malloc(512);
char *src = (char*)malloc(1024);
...
dst = (char*)realloc(dst, 1024);
memcpy(dst, src, 1024);

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


5
如果您不关心旧内容,为什么不直接使用free/malloc函数释放/分配缓冲区呢? - Mat
5
不要对 malloc() 的返回值进行转换。这样做最多是多余的,而且可能会掩盖一个编译器本应捕获的错误。 - pmg
1
遗憾的是,在C++中编写C风格代码时,您必须进行强制类型转换。我敢打赌这就是发生的事情。 - user606723
我理解为什么内存不能可靠地扩展。但是缩小分配的大小是否可靠呢?例如,我会过度分配一块内存池,当程序达到稳态时,我将重新分配该内存池以减小其大小。 - KANJICODER
1
@Mat:减少内存碎片化可能是一个原因。 - Tara
真糟糕,我需要这个。当为动态数组制作“插入”函数时,避免双重复制可以极大地提高效率。 - user426
3个回答

3
为什么不采用以下方法:
free(dst);
dst = malloc(1024);

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


5
如果realloc重新分配内存失败,它并不会丢失旧的指针。相反,如果调用代码在覆盖旧指针之前没有检查失败,就会导致旧指针丢失。 - R.. GitHub STOP HELPING ICE

2

realloc尝试扩展缓冲区而不进行复制,但只有在额外的空间是空闲的情况下才能这样做。

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


谢谢。是的,你说得对。实际上我的意思是...使用HeapReAlloc()函数并设置flag=HEAP_REALLOC_IN_PLACE_ONLY来尝试扩展缓冲区大小,如果失败了,就直接分配一个新的块而不复制数据。你知道HeapReAlloc()是操作系统API,我不想处理堆内存。所以我认为在C库中可能应该有一个像我想要的函数。 - legendlee

-1
所以有没有任何库中的函数符合我的要求?
不,没有。如果没有空间,系统应该如何扩展内存块?
例如,想象一下你这样做:
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个字节的指针。

7
是的,你是对的,所以经常进行“移动”操作。但我希望系统能够做的是:“如果无法扩展物品a,则只需分配一个新物品,但不要复制数据,我不需要它”。 - legendlee
@legendlee 标准C中不存在这样的东西。如果您无论如何都不关心数据,那么您可以使用malloc()吗? - nos
2
@nos 首先需要一个 free,然后是一个 malloc。虽然使用这种假设操作时,您会首先尝试在不释放已分配的内存的情况下扩展它,这可能更有效率。 - Antonio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接