What does malloc(0) return?

c, linux, malloc, pointers, realloc

Solution

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)`:

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

The standard says this about `realloc(ptr, size)`:

- 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`.

So, there are two cases:

- `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.

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`.

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))

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()`.

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.)

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");

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

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

Problem

What does `malloc(0)` return? Would the answer be same for `realloc(malloc(0),0)`? ``` #include<stdio.h> #include<malloc.h> int main() { printf("%p\n", malloc(0)); printf("%p\n", realloc(malloc(0), 0)); return 0; } ``` Output from Linux GCC: ``` manav@manav-workstation:~$ gcc -Wall mal.c manav@manav-workstation:~$ ./a.out 0x9363008 (nil) manav@manav-workstation:~$ ``` 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? EDIT: If `malloc(0)` returns dummy pointer, then how does following works: ``` int main() { void *ptr = malloc(0); printf("%p\n", realloc(ptr, 1024)); return 0; } ``` EDIT: 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\n"); for (i=0; i<65000; i++) { ptr = malloc(0); if (ptr == realloc(ptr, 1024)) printf("Iteration %d: possible\n", i); else { printf("Failed for iteration %d\n", i); break; } } return 0; } ```

Original source

Related problems