4 ms·
Sadly, this pattern doesn't work with standard realloc() anymore. C23 makes this undefined behavior due to existing non-conforming implementations. https://www
by torstenvl 3y ago
Sadly, this pattern doesn't work with standard realloc() anymore. C23 makes this undefined behavior due to existing non-conforming implementations.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf
- kazinator 3y agoThe pattern was never specified as fully working. Not in C99 and C90. It's due to the following reason: it was never specified that realloc(ptr, 0) behaves like free(ptr). The case of size == 0 is not separately discussed in the C99 description of realloc. realloc(ptr, 0) can behave like (free(ptr), malloc(0)), where malloc(0) doesn't necessarily behave like ((void *) 0). Malloc may return a unique object that may be later freed. That is to say, realloc can effectively reduce an object to zero size without freeing it, or possibly even free an object only to replace it with a different, unique zero-sized object. Note that in the case when ptr == NULL, which is discussed in C99, realloc behaves like malloc. So in the case realloc(NULL, 0), we know that it's the same as malloc(0). That's a case when size == 0, and realloc is required to behave like malloc. This is a standard-conforming realloc, and always has been: void *realloc(void *oldptr, size_t newsize) { size_t oldsize = __allocated_size(oldptr); // this handles NULL, and returns 0 void *newptr = malloc(newsize); if (newptr != NULL && oldptr != NULL) memcpy(newptr, oldptr, min(newsize, oldsize); return newptr; } This realloc will not behave like free if malloc(0) returns unique pointers. If you want a realloc-like function that behaves like an "all in one allocator", you have to write your own: void *git_reset_of_allocators(void *oldptr, size_t newsize) { if (size == 0) { free(oldptr); return NULL; } else { // handles all other cases OK return realloc(oldptr, newsize); } }
- torstenvl 3y agoI stand corrected! Thanks :)
- dataflow 3y agoPOSIX loosened its guarantee here too? https://pubs.opengroup.org/onlinepubs/009696899/functions/realloc.html https://pubs.opengroup.org/onlinepubs/009696899/functions/re... https://pubs.opengroup.org/onlinepubs/9699919799/functions/realloc.html https://pubs.opengroup.org/onlinepubs/9699919799/functions/r...
- spacechild1 3y ago> Sadly, this pattern doesn't work with standard realloc() anymore It never really did and it wasn't supposed to.