Live data from Hacker News

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

utcc.utoronto.ca

21–30 of 84 posts

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

#21

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

I might be missing something, but how does this help in checking for leaks? I mean, I guess you could use it to check for leaks specifically of 0-sized allocations, but wouldn’t it be better just to return NULL and guarantee that 0-sized allocations never use any memory at all?

> but wouldn’t it be better just to return NULL and guarantee that 0-sized allocations never use any memory at all?

This works if you are only interested in the overall memory balance. However, if you want to make sure that all malloc() calls are matched by a free() call, you need to distinguish between NULL and a successfull zero-sized allocation, otherwise you run into troubles when you call free on an "actual" NULL pointer (which the standard defines as a no-op).

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

#22
post #11

Earlier quoted context omitted.

There are three reasonable choices: (a) return the null pointer (b) return a valid unique pointer and (c) abort(). The point of the original C Standard was to make rules about these things AND not break existing implementations. They recognized that (a) and (b) were in existing implementations and were reasonable, and they chose not to break the existing implementations when writing the standard. This is similar to t…

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

> allocating a few bytes that weren't asked for.

FWIW the alignment guarantees of `malloc()` mean it often will have to allocate more than you ask for (before C23 anyway). You can't 'legally' use this space, but `malloc()` also can't repurpose it for other allocations because it's not suitably aligned.

That said I still agree it's a hack compared to just using `malloc(1)` for this purpose, it's well-defined and functionally equivalent if you're looking for a unique address. The fact that you don't know what `malloc(0)` is going to do makes it pretty useless anyway.

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

#23
post #11

Earlier quoted context omitted.

There are three reasonable choices: (a) return the null pointer (b) return a valid unique pointer and (c) abort(). The point of the original C Standard was to make rules about these things AND not break existing implementations. They recognized that (a) and (b) were in existing implementations and were reasonable, and they chose not to break the existing implementations when writing the standard. This is similar to t…

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

The only requirement which seems reasonable to me, is that the address be unique. Since the allocation size is zero, it should never be accessed for read or write, but the address itself may need to be used for comparisons.

If you’re pointing to a zero sized data it shouldn’t matter what it’s pointing to. Even outside valid address space. Because you shouldn’t be reading or writing more than 0 bytes anyway.

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

#24
post #11

Earlier quoted context omitted.

There are three reasonable choices: (a) return the null pointer (b) return a valid unique pointer and (c) abort(). The point of the original C Standard was to make rules about these things AND not break existing implementations. They recognized that (a) and (b) were in existing implementations and were reasonable, and they chose not to break the existing implementations when writing the standard. This is similar to t…

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

> or allocating a few bytes that weren't asked for.

You are always allocating bytes you weren't asked for: the allocation metadata and some extra bytes to satisfy the alignment requirement. If you absolutely don't want to allocate memory, you probably shouldn't have called malloc() in the first place :)

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

#26

Earlier quoted context omitted.

I might be missing something, but how does this help in checking for leaks? I mean, I guess you could use it to check for leaks specifically of 0-sized allocations, but wouldn’t it be better just to return NULL and guarantee that 0-sized allocations never use any memory at all?

At the end of main, if the count wasn't balanced, then you knew you had a mismatch between malloc()/free(). If malloc() had returned a real pointer, you'd have to free that too. > wouldn’t it be better just to return NULL and guarantee that 0-sized allocations never use any memory at all? Better: takes less memory Worse: blinds you to this portability issue.

> At the end of main, if the count wasn't balanced, then you knew you had a mismatch between malloc()/free().

A mismatch between malloc(0) and free(-1).

You’d know nothing about calls to malloc with non-zero sizes.

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

#27
post #17

Earlier quoted context omitted.

> Noncompliant, since `malloc(0)` is specified to return a unique pointer if it's not `NULL`. I know I've seen that somewhere, but may I ask what standard you're referring to? If I recall correctly, this was an archaic stackless microcontroller. The heap support was mostly a marketing claim.

C89: https://port70.net/%7Ensz/c/c89/c89-draft.html If the size of the space requested is zero, the behavior is implementation-defined; the value returned shall be either a null pointer or a unique pointer.

Isn’t -1 basically 0xffff which is a constant pointer? What am I missinterpreting?

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

#28
post #27
post #17

Earlier quoted context omitted.

C89: https://port70.net/%7Ensz/c/c89/c89-draft.html If the size of the space requested is zero, the behavior is implementation-defined; the value returned shall be either a null pointer or a unique pointer.

Isn’t -1 basically 0xffff which is a constant pointer? What am I missinterpreting?

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

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

#29

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.

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

#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 that: to return either NULL or else a unique pointer where that the program has permission to use zero bytes starting at that pointer.

Post reply on HN