malloc(0) 返回什么? [英] What does malloc(0) return?

查看:50
本文介绍了malloc(0) 返回什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

malloc(0) 返回什么?

realloc(malloc(0),0) 的答案是否相同?

#include<stdio.h>
#include<malloc.h>
int main()
{
        printf("%p
", malloc(0));
        printf("%p
", realloc(malloc(0), 0));
        return 0;
}

Linux GCC 的输出:

Output from Linux GCC:

manav@manav-workstation:~$ gcc -Wall mal.c
manav@manav-workstation:~$ ./a.out
0x9363008
(nil)
manav@manav-workstation:~$

malloc(0) 的输出每次都在不断变化.这是标准答案吗?除了学术研究之外,为什么会有人对获得这样的指针感兴趣?

The output keep changing everytime for malloc(0). Is this a standard answer? And why would anyone be interested in getting such a pointer, other than academic research?

如果 malloc(0) 返回虚拟指针,那么下面是如何工作的:

If malloc(0) returns dummy pointer, then how does following works:

int main()
{
    void *ptr = malloc(0);
    printf("%p
", realloc(ptr, 1024));
    return 0;
}

以下代码为每次迭代输出可能".为什么不应该失败?

The following code outputs "possible" for every iteration. Why should it not fail ?

#include<stdio.h>
#include<malloc.h>
int main()
{

        int i;
        void *ptr;
        printf("Testing using BRUTE FORCE
");
        for (i=0; i<65000; i++)
        {
                ptr = malloc(0);
                if (ptr == realloc(ptr, 1024))
                        printf("Iteration %d: possible
", i);
                else
                {
                        printf("Failed for iteration %d
", i);
                        break;
                }
        }
        return 0;
}

推荐答案

其他人已经回答了 malloc(0) 的工作原理.我将回答您提出的尚未回答的问题之一(我认为).问题是关于 realloc(malloc(0), 0):

Others have answered how malloc(0) works. I will answer one of the questions that you asked that hasn't been answered yet (I think). The question is about realloc(malloc(0), 0):

malloc(0) 返回什么?realloc(malloc(0),0) 的答案是否相同?

What does malloc(0) return? Would the answer be same for realloc(malloc(0),0)?

标准是关于realloc(ptr, size)的:

  • 如果 ptrNULL,它的行为就像 malloc(size),
  • 否则(ptr 不是 NULL),它会释放 ptr 指向的旧对象指针,并返回一个指向新分配缓冲区的指针.但是如果 size 为 0,C89 说效果等同于 free(ptr).有趣的是,我在 C99 草案(n1256 或 n1336)中找不到该声明.在 C89 中,在这种情况下返回的唯一合理值是 NULL.
  • if ptr is NULL, it behaves like malloc(size),
  • otherwise (ptr is not NULL), it deallocates the old object pointer to by ptr and returns a pointer to a new allocated buffer. But if size is 0, C89 says that the effect is equivalent to free(ptr). Interestingly, I can't find that statement in C99 draft (n1256 or n1336). In C89, the only sensible value to return in that case would be NULL.

所以,有两种情况:

  • malloc(0) 在实现上返回 NULL.那么你的 realloc() 调用等价于 realloc(NULL, 0).这相当于上面的 malloc(0)(在这种情况下是 NULL).
  • malloc(0) 返回非NULL.然后,调用等效于 free(malloc(0)).在这种情况下,malloc(0)realloc(malloc(0), 0)等价的.
  • malloc(0) returns NULL on an implementation. Then your realloc() call is equivalent to realloc(NULL, 0). That is equivalent to malloc(0) from above (and that is NULL in this case).
  • malloc(0) returns non-NULL. Then, the call is equivalent to free(malloc(0)). In this case, malloc(0) and realloc(malloc(0), 0) are not equivalent.

注意这里有一个有趣的例子:在第二种情况下,当malloc(0)成功返回非NULL时,它可能仍然返回NULL 表示失败.这将导致一个类似的调用:realloc(NULL, 0),它等价于 malloc(0),它可能返回也可能不返回 NULL.

Note that there is an interesting case here: in the second case, when malloc(0) returns non-NULL on success, it may still return NULL to indicate failure. This will result in a call like: realloc(NULL, 0), which would be equivalent to malloc(0), which may or may not return NULL.

我不确定 C99 中的遗漏是否是疏忽,或者是否意味着在 C99 中,realloc(ptr, 0) 用于非 NULL ptr 不等同于 free(ptr).我刚刚用 gcc -std=c99 尝试了这个,上面相当于 free(ptr).

I am not sure if the omission in C99 is an oversight or if it means that in C99, realloc(ptr, 0) for non-NULL ptr is not equivalent to free(ptr). I just tried this with gcc -std=c99, and the above is equivalent to free(ptr).

编辑:我想我明白你的困惑是什么:

Edit: I think I understand what your confusion is:

让我们看一下示例代码中的一个片段:

Let's look at a snippet from your example code:

ptr = malloc(0);
if (ptr == realloc(ptr, 1024))

以上与malloc(0) == realloc(malloc(0), 1024) 不一样.在第二个中,malloc() 调用两次,而在第一个中,您将先前分配的指针传递给 realloc().

The above is not the same as malloc(0) == realloc(malloc(0), 1024). In the second, the malloc() call is made twice, whereas in the first, you're passing a previously allocated pointer to realloc().

我们先来分析一下第一个代码.假设 malloc(0) 在成功时不返回 NULLptr 具有有效值.当您执行 realloc(ptr, 1024) 时,realloc() 基本上会给您一个大小为 1024 的新缓冲区,并且 ptr 变为无效的.符合要求的实现可能会返回与 ptr 中已有的地址相同的地址.因此,您的 if 条件可能会返回 true.(但是请注意,在 realloc(ptr, 1024) 之后查看 ptr 的值可能是未定义的行为.)

Let's analyze the first code first. Assuming malloc(0) doesn't return NULL on success, ptr has a valid value. When you do realloc(ptr, 1024), realloc() basically gives you a new buffer that has the size 1024, and the ptr becomes invalid. A conforming implementation may return the same address as the one already in ptr. So, your if condition may return true. (Note, however, looking at the value of ptr after realloc(ptr, 1024) may be undefined behavior.)

现在你问的问题是:malloc(0) == realloc(malloc(0), 1024).在这种情况下,我们假设 LHS 和 RHS 上的 malloc(0) 都返回非 NULL.那么,它们肯定是不同的.此外,LHS 上 malloc() 的返回值还没有被 free()d,所以任何其他 malloc()calloc()realloc() 可能不会返回该值.这意味着,如果您将条件写为:

Now the question you ask: malloc(0) == realloc(malloc(0), 1024). In this case, let's assume that both the malloc(0) on the LHS and RHS returns non-NULL. Then, they are guaranteed to be different. Also, the return value from malloc() on the LHS hasn't been free()d yet, so any other malloc(), calloc(), or realloc() may not return that value. This means that if you wrote your condition as:

if (malloc(0) == realloc(malloc(0), 1024)
    puts("possible");

您不会在输出中看到 possible(除非 malloc()realloc() 都失败并返回 NULL).

you won't see possible on the output (unless both malloc() and realloc() fail and return NULL).

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    void *p1;
    void *p2;

    p1 = malloc(0);
    p2 = realloc(p1, 1024);
    if (p1 == p2)
        puts("possible, OK");

    /* Ignore the memory leaks */
    if (malloc(0) == realloc(malloc(0), 1024))
        puts("shouldn't happen, something is wrong");
    return 0;
}

在 OS X 上,我的代码在运行时没有输出任何内容.在 Linux 上,它打印 possible, OK.

On OS X, my code didn't output anything when I ran it. On Linux, it prints possible, OK.

这篇关于malloc(0) 返回什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆