简体   繁体   English

使用 realloc 收缩分配的 memory

[英]Using realloc to shrink the allocated memory

Simple question about the realloc function in C: If I use realloc to shrink the memory block that a pointer is pointing to, does the "extra" memory get freed? Simple question about the realloc function in C: If I use realloc to shrink the memory block that a pointer is pointing to, does the "extra" memory get freed? Or does it need to be freed manually somehow?还是需要以某种方式手动释放?

For example, if I do例如,如果我这样做

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

Will I have a memory leak?我会有 memory 泄漏吗?

No, you won't have a memory leak.不,您不会有 memory 泄漏。 realloc will simply mark the rest "available" for future malloc operations. realloc将简单地将 rest 标记为“可用”以供将来的malloc操作使用。

But you still have to free myPointer later on.但是您仍然需要稍后free myPointer As an aside, if you use 0 as the size in realloc , it will have the same effect as free on some implementations .顺便说一句,如果您在realloc中使用0作为大小,它在某些 implementations上将具有与free相同的效果。 As Steve Jessop and R.. said in the comments, you shouldn't rely on it.正如 Steve Jessop 和 R.. 在评论中所说,你不应该依赖它。

There is definitely not a memory leak, but any of at least 3 things could happen when you call realloc to reduce the size:绝对没有 memory 泄漏,但是当您调用realloc以减小大小时,至少会发生 3 件事:

  1. The implementation splits the allocated memory block at the new requested length and frees the unused portion at the end.该实现以新请求的长度拆分分配的 memory 块,并在最后释放未使用的部分。
  2. The implementation makes a new allocation with the new size, copies the old contents to the new location, and frees the entire old allocation.该实现使用新大小进行新分配,将旧内容复制到新位置,并释放整个旧分配。
  3. The implementation does nothing at all.实现什么都不做。

Option 3 would be a rather bad implementation, but perfectly legal;选项 3 将是一个相当糟糕的实现,但完全合法; there's still no "memory leak" because the whole thing will still be freed if you later call free on it.仍然没有“内存泄漏”,因为如果你稍后调用它,整个东西仍然会被free

As for options 1 and 2, which is better depends a lot on whether you favor performance or avoiding memory fragmentation.至于选项 1 和 2,哪个更好取决于您是偏爱性能还是避免 memory 碎片。 I believe most real-world implementations will lean towards doing option 1.我相信大多数现实世界的实现都倾向于选择选项 1。

The new code still leaks the original allocation if the realloc fails.如果重新分配失败,新代码仍然会泄漏原始分配。 I expect most implementations won't ever fail to shrink a block, but it's allowed.我希望大多数实现都不会缩小块,但这是允许的。 The correct way to call realloc, whether growing or shrinking the block, is void *tmp = realloc(myPointer, 50*sizeof(int));调用 realloc 的正确方法,无论是增大还是缩小块,都是 void *tmp = realloc(myPointer, 50*sizeof(int)); if (.tmp) { /* handle error somehow, myPointer still points to the old block; if (.tmp) { /* 以某种方式处理错误,myPointer 仍然指向旧块; which is still allocated */ } myPointer = tmp.. – Steve Jessop 48 mins ago仍然分配 */ } myPointer = tmp.. – Steve Jessop 48 分钟前

Hey, I couldn't figure out how to reply to your comment, sorry.嘿,我不知道如何回复你的评论,对不起。

Do I need to cast tmp to the type of myPointer?我需要将 tmp 转换为 myPointer 的类型吗? In this case, do I need to write在这种情况下,我是否需要写

myPointer = (int*)tmp

Also, in this case, when I do free(myPointer) The memory pointed at by tmp will be freed as well, right?另外,在这种情况下,当我执行 free(myPointer) 时,tmp 指向的 memory 也会被释放,对吧? So no need to do所以不需要做

free(myPointer)
free(tmp)

In the way you have given your code, yes, it might have a leak.以您提供代码的方式,是的,它可能有泄漏。 The idea of realloc is that it can return you a new location of your data. realloc的想法是它可以为您返回数据的新位置。 Like you do it in your question you lose that pointer that realloc sends you.就像您在问题中这样做一样,您会丢失realloc发送给您的指针。

int *myPointer2 = realloc(myPointer,50*sizeof(int));
assert(myPointer2); 
myPointer = myPointer2;

I guess the process for realloc() is, it first dealocates the previous memory block then, allocates again (My college teacher told that).我猜 realloc() 的过程是,它首先释放之前的 memory 块,然后再次分配(我的大学老师告诉过)。 If that remains the case, it would have already freed the extra 50 bytes.如果情况仍然如此,它已经释放了额外的 50 个字节。 And if there is data in 100 byte memory, will get assigned to 50 reallocated bytes memory, which may, lead to loss of data.如果 100 字节 memory 中有数据,则会重新分配给 50 字节 memory,这可能会导致数据丢失。 So there shouldn't be a Memory Leak.所以不应该有 Memory 泄漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM