使用realloc缩小分配的内存

Mos*_*ein 26 c memory-management realloc

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

例如,如果我这样做

int *myPointer = malloc(100*sizeof(int));
myPointer = realloc(myPointer,50*sizeof(int));
free(myPointer);
Run Code Online (Sandbox Code Playgroud)

我会有内存泄漏吗?

cni*_*tar 20

不,你不会有内存泄漏.realloc将简单地标记其余的"可用"以用于将来的malloc操作.

但你以后还是要free myPointer等.顺便说一句,如果你使用0大小realloc,它将具有与free 某些实现相同的效果.正如Steve Jessop和R ..在评论中所说,你不应该依赖它.

  • "如果在realloc中使用0作为大小,它将具有与free相同的效果." - 在您的实施中可能是真的,但不能保证.如果`realloc`从0输入返回空指针,并且未将errno设置为ENOMEM,则释放内存.但就像malloc一样,realloc允许尝试返回0可用大小的实际分配.需要实施哪些文件(7.20.3/1). (3认同)
  • 史蒂夫是对的,这样做的实际结果是你永远不应该调用大小为0的`realloc`.处理所有可能的行为,存在不一致的实现,以及C和POSIX的事实似乎不同意什么是一致的,什么不是一个非常糟糕的主意依赖与`realloc(x,0)`相关的任何东西. (3认同)

R..*_*R.. 15

肯定没有内存泄漏,但是当你调用realloc缩小大小时,至少有3件事情会发生:

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

选项3将是一个相当糟糕的实施,但完全合法; 仍然没有"内存泄漏",因为如果你以后再打电话free,整个事情仍将被释放.

对于选项1和2,哪个更好取决于您是喜欢性能还是避免内存碎片.我相信大多数现实世界的实施都倾向于选择1.

  • 假设您分配了100个字节,并希望将其调整为50个字节.第一个分配声明了一个100字节的空闲区域,选项1返回了一个50字节的空闲区域,但是更长的100字节区域不再可用.但是,如果有另一个只有50个字节长的自由区,则选项2可以将数据移动到该位置并释放一个100字节的区域,从而使内存更少碎片化. (4认同)

azp*_*are 6

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

嘿,我不知道如何回复你的评论,抱歉。

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

myPointer = (int*)tmp
Run Code Online (Sandbox Code Playgroud)

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

free(myPointer)
free(tmp)
Run Code Online (Sandbox Code Playgroud)