Live data from Hacker News

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

utcc.utoronto.ca

61–70 of 84 posts

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

#61

Earlier quoted context omitted.

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

Like swimming in a bucket of rusty knives :)

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

#62

Earlier quoted context omitted.

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

But adding 1 to a pointer will add sizeof(T) to the underlying value, so you actually need to reserve more than two addresses if you want to distinguish the "past-the-end" pointer for every object from NULL.

--

While it's rare to find a platform nowadays that uses something other than a zero bit pattern for NULL as normal pointer type; it's extremely common in C++ for pointer-to-member types: 0 is the first field at the start of a struct (offset 0); and NULL is instead represented with -1.

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

#63

Earlier quoted context omitted.

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.

But the letter is non-specific. It doesn't clarify if unique refers to unique when compared to non-zero allocations, or unique when called multiple times.

The C99 standard[1] seems to have worded it more precisely:

If the size of the space requested is zero, the behavior is implementation- defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

[1]: https://rgambord.github.io/c99-doc/sections/7/20/3/index.htm...

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

#64

Earlier quoted context omitted.

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.

This is embedded C where standard abuse is a thing: https://thephd.dev/conformance-should-mean-something-fputc-a...

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

#65
post #28
post #27

Earlier quoted context omitted.

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.

Null is not a unique pointer, it's a contant like -1

It returns multiple types of null pointer

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

#66
post #62

Earlier quoted context omitted.

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…

But adding 1 to a pointer will add sizeof(T) to the underlying value, so you actually need to reserve more than two addresses if you want to distinguish the "past-the-end" pointer for every object from NULL. -- While it's rare to find a platform nowadays that uses something other than a zero bit pattern for NULL as normal pointer type; it's extremely common in C++ for pointer-to-member types: 0 is the first field at…

> so you actually need to reserve more than two addresses if you want to distinguish the "past-the-end" pointer for every object from NULL.

Well, yes and no. A 4-byte int can not reside at -4, but a char could be; but no object can reside at -1. So implementations need to take care that one-past-the-end addresses never equal to whatever happens to serve as nullptr but this requirement only makes address -1 completely unavailable for the C-native objects.

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

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

Something separate that occurred to me - many systems have empty sections of address space, those addresses can't back `malloc(1)` allocations but they could back `malloc(0)` allocations with a unique address. I doubt any C runtime out there will actually do that, but in theory it could be done.

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

#68
post #59
post #3

Earlier quoted context omitted.

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!

My next malloc(3) is returning NAN.

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

#69
post #68
post #59

Earlier quoted context omitted.

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

My next malloc(3) is returning NAN.

I've always considered NaN too definitive for general industry languages like C, JS or Cobol where not even physics with calculus should be assumed. Maybe its ok for languages that at least expect math for engineers like Fortran or up..

How about we call it "Maybe a Number" and since equality can't work for it we still need a separate way to ask like: Math.whoIsTheMaN(me)

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

#70
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.

Null is not a unique pointer, it's a contant like -1 It returns multiple types of null pointer

The spec says that malloc(0) shall return "either a null pointer or a unique pointer". If it's null, it doesn't have to be unique.
Post reply on HN