我可以假设用较小的大小调用realloc可以释放余数吗?

qdi*_*dii 26 c malloc free realloc

让我们考虑一下这段很短的代码片段:

#include <stdlib.h>

int main()
{
    char* a = malloc(20000);
    char* b = realloc(a, 5);

    free(b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在阅读了realloc的手册页后,我不完全确定第二行会导致释放19995个额外字节.引用手册页:The realloc() function changes the size of the memory block pointed to by ptr to size bytes.但是根据该定义,我可以确定其余的将被释放吗?

我的意思是,指向的块b肯定包含5个空闲字节,所以对于懒惰的顺从分配器是否足以让realloc行不做任何事情?

注意:我使用的分配器似乎释放了19 995个额外字节,如valgrind在注释掉free(b)行时所示:

==4457== HEAP SUMMARY:
==4457==     in use at exit: 5 bytes in 1 blocks
==4457==   total heap usage: 2 allocs, 1 frees, 20,005 bytes allocated
Run Code Online (Sandbox Code Playgroud)

oua*_*uah 25

是的,如果可以分配新对象,则由C标准保证.

(C99,7.20.3.4p2)"realloc函数解除分配ptr指向的旧对象,并返回指向大小指定大小的新对象的指针."

  • C997.20.3.4§4:*realloc函数返回一个指向新对象的指针(可能与指向旧对象的指针具有相同的值)* (3认同)

Ada*_*iss 20

是的 - 如果成功的话.

您的代码段显示了一个众所周知的恶意错误:

char* b = (char*) realloc(a, 5);
Run Code Online (Sandbox Code Playgroud)

如果成功,a则将释放先前分配给的内存,并b指向可能与原始块重叠或不重叠的5字节内存.

但是,如果调用失败,b将会null,但a仍将指向其原始内存,这仍然有效.在这种情况下,您需要free(a)释放内存.

如果你使用常见的(危险的)成语,情况会更糟:

a = realloc(a, NEW_SIZE);     // Don't do this!
Run Code Online (Sandbox Code Playgroud)

如果调用realloc失败,则会出现null并且其原始内存将被孤立,使其无法恢复,直到您的程序退出.

  • 是的,这确实发生在现实世界中。为什么您认为当您耗尽内存(在没有交换的系统上)时,这么多蹩脚的软件会崩溃,而不是给您一条消息,表明由于内存不足而无法执行请求的操作? (2认同)