c - 允许什么分配返回值?

标签 c malloc language-lawyer

哪些函数可能返回 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;
    }
}

realloc失败,malloc成功

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 的任何给定值终止此函数是特定于实现的。大多数系统最终会回收释放的 block 并且永远不会重新分配 a字节,但系统中 free什么都不做仍然符合标准,循环最终可能会失败。

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

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

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

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

关于c - 允许什么分配返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51224761/

相关文章:

c - 另一个大小的数组

c - 在 C 中初始化结构体 GHashTable

c - Malloc Typedef 结构问题

c++ - 打印结构的结构数组会导致意外的执行错误?

C++语法产生: class-head

c - 在机器代码中查找位置 (gcc/objdump -d)

c - 在 C 中限制程序的执行时间(蒙特卡罗技术)

c - 关于 sizeof() 和分配的内存

c - malloc 如何使用严格的别名 - 它只能在单个编译单元内被违反吗?

c - gets_s() 预期行为