Hi all,
there's an ongoing thread on the musl mailing list right now (plus a couple of others) about malloc(0) and realloc(p, 0), specifically about making them consistent with each other. And while reading that thread I was constantly wondering if I was taking crazy pills.
In all my life, I have seen a lot of C code, I have written a lot of C code, and I have debugged quite a lot of C code. And in that time, never, not once, have I had occasion to use malloc(0) for anything. But suddenly there's this dude really passionately arguing that malloc should be required to attempt to allocate a zero-sized object if called with 0 as argument. And other people I previously respected agree with him! Why in three devils' name should malloc() do such a thing? C doesn't have any zero-sized types, and so cannot have zero-sized objects. Consequently, I made my version of malloc return NULL/EINVAL when someone attempts to allocate 0 bytes.
And realloc(p, 0) I have never understood. What is the point? realloc() can only return NULL or a valid pointer, right? And NULL means an error occurred and the original pointer is still valid. So realloc(p, 0) cannot have the meaning of freeing the pointer, because then p is no longer a valid pointer to return, and it cannot return NULL because that would mean error and no side effects. My version of realloc returns NULL/EINVAL and has no side effects.
So what about you guys? Have you ever seen malloc(0) and realloc(p, 0) honestly used for anything in an application? Or is that thread just an academic ivory tower discussion of the highest order?
How common are malloc(0) and realloc(p, 0)?
How common are malloc(0) and realloc(p, 0)?
Carpe diem!
-
- Member
- Posts: 5858
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How common are malloc(0) and realloc(p, 0)?
The primary use, as far as I can tell, is being compliant with the C standard without requiring different versions of realloc depending on the version of the C standard.
I mean, it could hypothetically also be useful if you need a bunch of unique handles that each may or may not have additional data associated with it and don't want to allocate a separate pointer for each handle and eat the costs of an extra level of indirection to access the optional per-handle data... but that's only hypothetical, I don't think I've seen a situation like that in reality.
C90 says that realloc(p, 0) will always free the original pointer no matter what it returns.
C99 and C11 say that realloc(p, 0) won't free the original pointer if it returns NULL.
C17 says it's implementation-defined whether realloc(p, 0) will free the original pointer if it returns NULL.
So, allowing zero-sized allocations means there's no disagreement on whether the original pointer is still valid when realloc returns NULL.
(C23 says realloc(p, 0) is undefined behavior...)
Re: How common are malloc(0) and realloc(p, 0)?
What you are describing, I would just implement as an array of pointers, and set the pointers NULL if no additional data is present.Octocontrabass wrote: ↑Tue Jun 17, 2025 11:15 pm I mean, it could hypothetically also be useful if you need a bunch of unique handles that each may or may not have additional data associated with it and don't want to allocate a separate pointer for each handle and eat the costs of an extra level of indirection to access the optional per-handle data... but that's only hypothetical, I don't think I've seen a situation like that in reality.
That explains why it was off my radar: I don't aim that low.Octocontrabass wrote: ↑Tue Jun 17, 2025 11:15 pm C90 says that realloc(p, 0) will always free the original pointer no matter what it returns.
Jokes aside, the progression in your post tells me the feature is less useful every year, and best avoided in applications for that reason. And in my implementation, I will keep everything just the way it is now. Thank you, this has been very helpful.
Carpe diem!
- PavelChekov
- Member
- Posts: 114
- Joined: Mon Sep 21, 2020 9:51 am
- Location: Aboard the Enterprise
Re: How common are malloc(0) and realloc(p, 0)?
The only application I can think of where malloc(0) would be truly useful is if you have a loop that expands a dynamic array with realloc every cycle, and you want a pointer to realloc to start with, because the first element would be initialized as part of the loop. I'm not really sure how allocating zero bytes would actually work, though.
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe
Live Long And Prosper
Slava Ukraini!
Слава Україні!
The Final Frontier,
Space,
The Universe
Live Long And Prosper
Slava Ukraini!
Слава Україні!
-
- Member
- Posts: 5858
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How common are malloc(0) and realloc(p, 0)?
You don't need malloc(0) for that, realloc(NULL,size) is equivalent to malloc(size) so you can initialize the pointer to NULL.
Re: How common are malloc(0) and realloc(p, 0)?
As a test case, I have scoured the busybox source code for uses of this, figuring it would be a codebase with a certain reputation and of decent complexity. Busybox wraps all calls to realloc() into its own xrealloc() wrapper that does the right thing, actually, namely to treat NULL returns as a fatal error only if the size was nonzero (although that still means it invokes undefined behavior in C23).
But anyway, in all of busybox, I found a single use of xrealloc(p, 0): In its RPM code, if an RPM file contains 0 tags, then it will reallocate the NULL tags array to a size of 0 tags. That was the only place I could find where it might call xrealloc with a second argument of 0, assuming an absence of overflows (and in the presence of overflows, most of the code just breaks and crashes, anyway).
But anyway, in all of busybox, I found a single use of xrealloc(p, 0): In its RPM code, if an RPM file contains 0 tags, then it will reallocate the NULL tags array to a size of 0 tags. That was the only place I could find where it might call xrealloc with a second argument of 0, assuming an absence of overflows (and in the presence of overflows, most of the code just breaks and crashes, anyway).
Carpe diem!