Live data from Hacker News

Some bits on malloc(0) in C being allowed to return NULL

utcc.utoronto.ca

51–60 of 84 posts

Re: Some bits on malloc(0) in C being allowed to return NULL

#51

Ages ago I worked with a system where malloc(0) incremented a counter and returned -1. free(-1) decremented the counter. This way you could check for leaks :p

Does this work in practice? Now you have a bunch of invalid but non-NULL pointers flying around. NULL checks which would normally prevent you from accessing invalid pointers now will pass and send you along to deref your bogus pointer. Even hacking the compiler to treat -1 as equal to NULL as well wouldn't work since lots of software won't free NULL-like pointers.

> NULL checks which would normally prevent you from accessing invalid pointers now will pass and send you along to deref your bogus pointer.

Oddly, this is bog standard implementation specific behavior for standard C - caller accessing any result of malloc(0) is undefined behavior, and malloc(0) isn't required to return NULL - the reference heap didn't, and some probably still don't.

Re: Some bits on malloc(0) in C being allowed to return NULL

#52

I never had the use case to allocate 0 bytes of memory. If I would allocate 0 bytes of memory and get a pointer to it, I wouldn't care what the value of the pointer is since I am not allowed to dereference it anyways. But then again, why would I allocate 0 bytes of memory?

Sometimes it shakes out simpler for a generic container.

Ex: a vector using only a counter and pointer - you can use realloc() with fewer pointer validity checks.

Re: Some bits on malloc(0) in C being allowed to return NULL

#53
post #30

Why should it be allowed to return a valid pointers anyways? Surely it should always return NULL?

The behavior of malloc(x) for any positive value x is to either return NULL (meaning that the system was unable to provide a new chunk of memory to use) OR to return a unique pointer to X bytes of data which the program can use. By extension, if x == 0, doesn't it make sense for the system to either return NULL OR to return a pointer to 0 bytes of memory which the program can use? So the standard promises exactly tha…

[deleted]

Re: Some bits on malloc(0) in C being allowed to return NULL

#54

Why should it be allowed to return a valid pointers anyways? Surely it should always return NULL?

> Why should it be allowed to return a valid pointers anyways?

malloc(0) is allowed to return non-NULL because the standard decrees it.

One way of thinking is that all mallocated pointers must always be freed exactly once. Then you're portable.

Re: Some bits on malloc(0) in C being allowed to return NULL

#55

Can someone tell me a usecase where you want multiple allocations of size 0, each one with a unique address, and each one unique from any other allocation (hence necessarily removing that pointer from being allocated to anything else) but can't use malloc(1) instead? I think it would be much better if malloc(0) just returned 1 or -1 or something constant. If the programmer needs the allocation to have a unique addres…

Because zero-size types exist which you might want to take the address of. Possibly as a result of macro substitution or templating mechanism that only appears in certain build configurations. It means you don't need a bunch of special-case handling if one out of 27 types ends up with zero size in some situation. It just all works the same way. Especially the unique address part because that would be an annoying sour…

Yes. I believe zero sized types should be possible and they should all have the same address. Trying to deref the pointer is UB right away because you do not have the byte under that pointer. As it is, the malloc implementation now needs special casing for 0 sized allocations and different implementations special case it differently. C is supposed to be low level so surface this confusion up. Let the programmer decide if they want a unique address and reserve a byte or a non unique one with no overhead.

Re: Some bits on malloc(0) in C being allowed to return NULL

#56

Earlier quoted context omitted.

Does this work in practice? Now you have a bunch of invalid but non-NULL pointers flying around. NULL checks which would normally prevent you from accessing invalid pointers now will pass and send you along to deref your bogus pointer. Even hacking the compiler to treat -1 as equal to NULL as well wouldn't work since lots of software won't free NULL-like pointers.

> NULL checks which would normally prevent you from accessing invalid pointers now will pass and send you along to deref your bogus pointer. Oddly, this is bog standard implementation specific behavior for standard C - caller accessing any result of malloc(0) is undefined behavior, and malloc(0) isn't required to return NULL - the reference heap didn't, and some probably still don't.

Ah, that's my bad. Another day, another UB :)

Re: Some bits on malloc(0) in C being allowed to return NULL

#57

Earlier quoted context omitted.

> return a valid unique pointer A pointer to what, though? If the requester asked for 0 bytes of memory, you'd either be pointing to memory allocated for another purpose (!) or allocating a few bytes that weren't asked for. > This makes people unhappy for various reasons I read through all the links trying to figure out what those reasons might be and came up empty, I'm still curious why anybody would expect or rely…

You can copy from a zero sized pointer with memcpy, but not NULL.

That's about to change: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3322.pdf

Re: Some bits on malloc(0) in C being allowed to return NULL

#58
post #28

Earlier quoted context omitted.

If you call malloc(0) multiple times (without freeing in between) and get -1 each time, then the pointer is not unique.

But do we need a unique pointer or merely a pointer that is disjoint from all objects?

As per the specification, it has to be a unique pointer.

Being tasked to implement a specification typically means having to pass extensive conformance tests and having to answer for instances of noncompliance. You soon learn to follow the spec to the letter, to the best of your abilities, unless you can make a strong case to your management for each specific deviation.

Re: Some bits on malloc(0) in C being allowed to return NULL

#59
post #3

Ages ago I worked with a system where malloc(0) incremented a counter and returned -1. free(-1) decremented the counter. This way you could check for leaks :p

Noncompliant, since `malloc(0)` is specified to return a unique pointer if it's not `NULL`. On most platforms an implementation could just return adjacent addresses from the top half of the address space. On 32-bit platforms it doesn't take long to run out of such address space however, and you don't want to waste the space for a bitmap allocator. I suppose you could just use a counter for each 64K region or somethin…

Oh but no worries with compliance, it always returned a newly created -1, never repeating the same one!

Re: Some bits on malloc(0) in C being allowed to return NULL

#60

Earlier quoted context omitted.

cppreference isn't the standard, and while the text they write looks like it's the same verbiage that would be authoritative, it's not. (And there's some criticism of it from standards committee members in that regard). The current C standard text says: > The order and contiguity of storage allocated by successive calls to the aligned_alloc, calloc, malloc, and realloc functions is unspecified. The pointer returned i…

> Each such allocation shall yield a pointer to an object disjoint from any other object. Phrasing could be slightly more clear to prevent someone from making the argument that -1 is disjoint from all objects as it does not point to an object

And if you use 0 as the value of NULL pointer, then -1 can't ever point to an object (because adding 1 to it should generate a non-NULL pointer, so that pointer comparisons are not UB).

So yeah, C implementations have to reserve at least two addresses, not just one. By the way, the standard to this day allows NULL, when cast to a pointer type, to be something else than all-bits-zero pattern (and some implementations indeed took this opportunity).

Post reply on HN