C语言 允许分配哪些返回值?



这些函数中的哪一个可能返回 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;
}
}

无法重新定位,但成功重新定位

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;
}

除了你没有包括<stdlib.h>之外,没有令人信服的理由让foo1最终失败并返回1。对于任何给定的a值,此函数的终止是特定于实现的。大多数系统最终会回收释放的块,并且永远不会重新分配a字节,但是free什么都不做的系统仍然符合标准,循环最终可能会失败。

函数foo2会导致一个或多个内存泄漏。如果realloc()失败,它将返回1,但相同大小的malloc()成功。 虽然这种情况会令人惊讶,但不能保证重新分配区块失败(或NULLmalloc(a)失败(意味着下一次调用相同大小的malloc()也应该失败。

函数foo3具有潜在的未定义行为:不应在q = realloc(p, b)后使用p的值。如果块确实被重新分配,则p的值可以成为陷阱值,因此不应将其与任何东西进行比较。 您可以通过将p的值存储到unsigned char数组中并在调用realloc后比较字节值来解决此问题。然而,即使块没有移动,比较也可能会有所不同。似乎没有一种便携式方法来确定realloc()是否移动了块。

然而,在p不会成为陷阱值的系统上,确实有可能malloc(b)失败并realloc(p, b)成功并返回不同的地址:如果内存堆没有可用于malloc(b)的块,malloc将返回NULL,但是如果p之前有可用空间可以合并形成大小为b的块,realloc可能会成功并返回不同的地址。

所有这些测试都具有实现定义的行为。

相关内容

  • 没有找到相关文章