【发布时间】:2011-02-02 13:05:25
【问题描述】:
给定以下代码:
int *a = NULL;
a = calloc(1, sizeof(*a));
printf("%d\n", a);
a = realloc(a, 0);
printf("%d\n", a);
return (0);
返回:
4078904
0
这个 realloc 等同于 free 吗?
注意: 我在 WindowsXP 下使用 MinGW。
【问题讨论】:
给定以下代码:
int *a = NULL;
a = calloc(1, sizeof(*a));
printf("%d\n", a);
a = realloc(a, 0);
printf("%d\n", a);
return (0);
返回:
4078904
0
这个 realloc 等同于 free 吗?
注意: 我在 WindowsXP 下使用 MinGW。
【问题讨论】:
它可能等同于也可能不等同于在指针上调用free;结果是实现定义的。
来自 C99 标准(§7.20.3/1):
如果请求的空间大小为零,则行为是实现定义的:要么返回空指针,要么行为就好像大小是某个非零值,但返回的指针不应用于访问一个对象。
这适用于所有内存管理功能,包括realloc。
【讨论】:
realloc() 释放 - 释放 - 原始内存,然后对新大小执行相当于 malloc() 的操作,相当于 malloc(0)在这种情况下,然后获取您引用的行为。 key的区别是realloc()无条件先释放旧内存。
不一定。
它通常与 link that munissor posted 一样,但 Mac OS 10.5 手册页说:
如果 size 为零且 ptr 不为 NULL,则分配一个新的、最小大小的对象并释放原始对象。
什么是“最小尺寸对象”?好吧,任何分配器都会存储一些关于分配的信息,这会占用通常分配给用户的空间之外的空间。据推测,“最小尺寸对象”只是这些标头之一加上为用户保留的零字节空间。
我猜想这个条款的存在是为了支持标准化时存在的实现,并且这些实现对于调试分配行为很有用。
考虑两者的区别
for (int i=0; i<VERY_BIG_NUMBER; ++i){
char *p = malloc(sizeof(char[10]));
free(p);
}
和
for (int i=0; i<VERY_BIG_NUMBER; ++i){
char *p = malloc(sizeof(char[10]));
realloc(p,0);
}
通过malloc 和free 的合理实现,第一个剪辑不会无限制地消耗内存。但如果 realloc 实现返回那些“最小尺寸的对象”,它可能会。
当然,这个例子是人为的,它依赖于理解“最小尺寸对象”的含义,但我认为文本允许这样做。
简而言之,如果你意思是 free,你应该说free。
【讨论】:
【讨论】:
C99 标准 §7.20.3.4 (realloc) 说:
realloc 函数释放 ptr 指向的旧对象并返回一个 指向具有 size 指定大小的新对象的指针。新的内容 对象应与释放前的旧对象相同,直至两者中的较小者 新旧尺寸。新对象中超出旧对象大小的任何字节都有 不确定的值。
如果 ptr 是空指针,则 realloc 函数的行为类似于 malloc 函数 规定的大小。否则,如果 ptr 与先前返回的指针不匹配 calloc、malloc 或 realloc 函数,或者如果空间已被调用释放 对于 free 或 realloc 函数,行为是未定义的。如果记忆为新 对象不能被分配,旧对象没有被释放,它的值不变。
这清楚地表明旧对象已被释放(释放)。返回值可能是空指针,也可能是第 7.20.3 节的一般说明中指定的值:
如果请求的空间大小为零,则行为由实现定义: 返回一个空指针,或者行为就像大小是一些 非零值,但返回的指针不得用于访问对象。
无论哪种方式,您都不能取消引用返回的值:它可以用作free() 的参数,或者传递给其他函数,只要它们反过来不引用它。
【讨论】: