36

关于 C 中 realloc 函数的简单问题:如果我使用 realloc 来缩小指针指向的内存块,“额外”内存是否会被释放?还是需要以某种方式手动释放?

例如,如果我这样做

int *myPointer = malloc(100*sizeof(int));
myPointer = realloc(myPointer,50*sizeof(int));
free(myPointer);

我会有内存泄漏吗?

4

5 回答 5

28

不,你不会有内存泄漏。realloc将简单地将其余部分标记为“可用”以供将来malloc操作。

但你还是要free myPointer稍后。顺便说一句,如果您使用0as size in realloc,它将与free 某些 implementations具有相同的效果。正如 Steve Jessop 和 R.. 在评论中所说,你不应该依赖它。

于 2011-08-16T12:13:00.267 回答
21

realloc绝对没有内存泄漏,但是当您调用以减小大小时,至少会发生 3 件事:

  1. 该实现以新请求的长度拆分分配的内存块,并在最后释放未使用的部分。
  2. 该实现使用新大小进行新分配,将旧内容复制到新位置,并释放整个旧分配。
  3. 实现什么都不做。

选项 3 将是一个相当糟糕的实现,但完全合法;仍然没有“内存泄漏”,因为如果您稍后调用free它,整个事情仍然会被释放。

至于选项 1 和 2,哪个更好在很大程度上取决于您是偏爱性能还是避免内存碎片。我相信大多数现实世界的实现都倾向于选择选项 1。

于 2011-08-16T12:31:02.177 回答
6

如果重新分配失败,新代码仍然会泄漏原始分配。我希望大多数实现都不会缩小块,但这是允许的。调用 realloc 的正确方法,无论是增大还是缩小块,都是 void *tmp = realloc(myPointer, 50*sizeof(int)); if (!tmp) { /* 以某种方式处理错误。myPointer 仍然指向仍然分配的旧块 */ } myPointer = tmp;。——史蒂夫·杰索普 48 分钟前

嘿,我不知道如何回复你的评论,对不起。

我需要将 tmp 转换为 myPointer 的类型吗?在这种情况下,我是否需要写

myPointer = (int*)tmp

另外,在这种情况下,当我执行 free(myPointer) 时,tmp 指向的内存也会被释放,对吧?所以不需要做

free(myPointer)
free(tmp)
于 2011-08-16T13:36:50.737 回答
4

以您提供代码的方式,是的,它可能有泄漏。的想法realloc是它可以为您返回数据的新位置。就像您在问题中这样做一样,您会丢失realloc发送给您的指针。

int *myPointer2 = realloc(myPointer,50*sizeof(int));
assert(myPointer2); 
myPointer = myPointer2;
于 2011-08-16T12:37:26.420 回答
0

我猜 realloc() 的过程是,它首先释放前一个内存块,然后再次分配(我的大学老师告诉过)。如果情况仍然如此,它已经释放了额外的 50 个字节。如果 100 字节内存中有数据,则会重新分配 50 字节内存,这可能会导致数据丢失。所以不应该有内存泄漏。

于 2020-07-25T02:58:57.463 回答