top | item 43587647

(no title)

amavect | 11 months ago

I forgot to mention my own opinion. I think that malloc(0) ought to return a 0-sized object, and likewise realloc(ptr, 0) ought to resize the object to 0. Malloc and realloc always allocating feels more consistent to me. For a practical example, I have some code that reads an entire FILE stream into memory. This requires realloc with doubling the size every time. After finishing, I'd like to resize the buffer down to the total bytes read. If it reads 0 bytes, I'd like it to resize the buffer to 0.

I think my sane_realloc never freeing has much simpler behavior. As much as I hate the needless waste of 1 byte, if my code allocates thousands of 0-sized objects, I'd rather fix that before adding complexity to my sane_realloc.

With yours solving the 1 byte problem, it still interests me. We can simplify your code slightly.

  #define SANE_REALLOC_EMPTY ((void *) -1)

  void *sane_realloc(void *ptr, size_t size)
  {
    if (ptr == SANE_REALLOC_EMPTY) {
      ptr = 0;
    }
    if (size == 0) {
      free(ptr);
      return SANE_REALLOC_EMPTY;
    } else {
      return realloc(ptr, size);
    }
  }

discuss

order

kazinator|11 months ago

A zero-sized object is immutable, since it has no bits to mutate. The pointer cannot be dereferenced. It may be compared to other pointers. So the question is: do you want to obtain unique zero-sized objects, or are you okay with there being one representative instance of all of them? If you're okay with one, you can just call SANE_REALLOC_EMPTY that object. I called it EMPTY on purpose; it represents an empty object with no bits.

If you want unique zero-sized objects, you can always simulate them with objects of size 1. The allocator API doesn't have to make that choice internally for you.

amavect|11 months ago

Like you, I have no idea what use the unique 0-sized pointers would provide. SANE_REALLOC_EMPTY is certainly adequate for me. Thank you!