以下哪个函数可能返回1?
分配和释放突然停止工作
int foo1(size_t a) {
void *t = malloc(a);
if (t == NULL)
return 0;
while (1) {
free(t);
t = malloc(a);
if (t == NULL)
return 1;
}
}
无法重新分配但成功分配m
int foo2(size_t a, size_t b) {
void *t = malloc(a);
if (realloc(t, b))
return 0;
if (malloc(b))
return 1;
return 0;
}
既不是新分配也不是纯扩展
int foo3(size_t a, size_t b) {
void *p, *q;
p = malloc(a);
if (malloc(b))
return 0;
q = realloc(p, b);
return p != q && q;
}
答案 0 :(得分:0)
除了您没有包括<stdlib.h>
的事实外,没有令人信服的理由使foo1
最终失败并返回1
。对于任何给定的a
值,此函数的终止是特定于实现的。大多数系统最终将回收释放的块,并且永远不会重新分配a
字节,但是free
不执行任何操作的系统仍然符合Standard,并且循环最终可能会失败。
函数foo2
导致一个或多个内存泄漏。如果1
失败,但相同大小的realloc()
成功,它将返回malloc()
。尽管这种情况令人惊讶,但无法保证无法重新分配块(或者NULL
失败了malloc(a)
)意味着对具有相同大小的malloc()
的下一次调用应该失败
函数foo3
具有潜在的不确定行为:您不应在p
之后使用q = realloc(p, b)
的值。如果确实重新分配了该块,则p
的值可以成为陷阱值,因此不应将其与任何内容进行比较。您可以通过将p
的值存储到unsigned char
数组中并在调用realloc
之后比较字节值来解决此问题。即使块没有移动,比较也可能会有所不同。似乎没有一种可移植的方法来确定realloc()
是否移动了该块。
尽管如此,在p
未成为陷阱值的系统上,实际上malloc(b)
失败而realloc(p, b)
成功并返回另一个地址的可能性很可能:如果内存堆没有对于malloc(b)
有一个可用块,malloc
将返回NULL
,但是如果p
之前有可用空间可以合并形成大小为{{1}的块},b
可能会成功并返回另一个地址。
所有这些测试都有实现定义的行为。