Most active commenters

    ←back to thread

    48 points ingve | 17 comments | | HN request time: 0.637s | source | bottom
    1. AaronDinesh ◴[] No.44389347[source]
    Why should it be allowed to return a valid pointers anyways? Surely it should always return NULL?
    replies(5): >>44389371 #>>44389461 #>>44389531 #>>44390081 #>>44392719 #
    2. Joker_vD ◴[] No.44389371[source]
    For instance, because you are prohibited from passing NULL to e.g. memcpy and lots of other library functions from memory.h/string.h, even when you explicitly specify a size of 0.

    Another use was to use it to mint unique cookies/addresses, but malloc(1) works for this just as well.

    replies(1): >>44389611 #
    3. snickerbockers ◴[] No.44389461[source]
    It's not a valid pointer because you can't use the indirection operator on it. Returning a value other than NULL makes sense because an allocation of size zero is still an allocation.

    Additionally the actual amount of memory malloc allocates is implementation-defined so long as it is not less than the amount requested, but accessing this extra memory is undefined behavior since processes don't know if it exists or not. a non-NULL return could be interpreted as malloc(0) allocating more than zero bytes.

    Some implementations don't actually perform the allocation until theres a pagefault from the process writing to or reading from that memory so in that sense a non-NULL return is valid too.

    I'd argue that malloc(0)==NULL makes less sense because there's no distinction between failure and success.

    The only real problem is specifying two alternate behaviors and declaring them both to be equally valid.

    4. cjensen ◴[] No.44389531[source]
    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 the extremely unfortunate definition of the NULL macro. There were two existing styles of implementation (bare literal 0 and (void *) 0) and the Standard allows either style. Which means the NULL macro is not entirely safe to use in portable code.

    replies(1): >>44389592 #
    5. commandlinefan ◴[] No.44389592[source]
    > 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 on anything except a null pointer in this instance.

    replies(5): >>44389671 #>>44389719 #>>44389745 #>>44389786 #>>44397812 #
    6. TZubiri ◴[] No.44389611[source]
    Mmmmh, cookies
    7. tedunangst ◴[] No.44389671{3}[source]
    You can copy from a zero sized pointer with memcpy, but not NULL.
    replies(1): >>44394792 #
    8. DSMan195276 ◴[] No.44389719{3}[source]
    > 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.

    replies(1): >>44390146 #
    9. AaronAPU ◴[] No.44389745{3}[source]
    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.

    10. spacechild1 ◴[] No.44389786{3}[source]
    > 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 :)

    11. mcherm ◴[] No.44390081[source]
    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.

    replies(1): >>44392699 #
    12. Joker_vD ◴[] No.44390146{4}[source]
    > before C23 anyway

    Did they change "suitably aligned for any object type" to "suitably aligned for any object type with size less than or equal to what was requested" or something like in C23?

    replies(1): >>44390622 #
    13. JdeBP ◴[] No.44390622{5}[source]
    See https://news.ycombinator.com/item?id=44390258 .
    14. ◴[] No.44392699[source]
    15. bobmcnamara ◴[] No.44392719[source]
    > 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.

    16. ncruces ◴[] No.44394792{4}[source]
    That's about to change: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3322.pdf
    17. DSMan195276 ◴[] No.44397812{3}[source]
    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.