Code in the article for realloc is dangerous and wrong:<p><pre><code> void *realloc(void *ptr, size_t size) {
void *nptr = malloc(size);
if (nptr == NULL) {
free(ptr);
return NULL;
}
memcpy(nptr, ptr, size); // KABOOM
free(ptr);
return nptr;
}
</code></pre>
Line marked KABOOM copies $DEST_BYTE_COUNT, rather than $SOURCE_BYTE_COUNT.<p>Say you want to realloc a 1 byte buffer to a 4 byte buffer - you just copied 4 bytes from a 1 byte buffer which means you're reading 3 bytes from 0xDEADBEEF/0xBADF000D/segfault land.<p>EDIT: Also, this is why the ENTIRE PREMISE of implementing your own reallocator speced to just the realloc prototype doesn't make much sense. You simply don't know the size of the original data with just a C heap pointer as this is not standardized AFAIK.
I have also found people often unestimate realloc (but have never done the same level of investigation to find out just how clever it is!)<p>On several occasions I have wanted to use mmap, mremap, and friends more often to do fancy things like copy-on-write memory. However, I always find this whole area depressingly poorly documented, and hard to do (because if you mess up a copy-on-write call, it just turns into a copy it seems, with the same result but less performance).<p>While it's good realloc is clever, I find it increasingly embarassing how badly C (and even worse, C++ which doesn't even really have realloc (as most C++ types can't be bitwise moved) memory allocation maps to what operating systems efficiently support.
This bothers me so much:<p><pre><code> buffer = realloc(buffer, capa);
</code></pre>
Yeah, 'cause when it fails we didn't need the old buffer anyway... Might as well leak it.
The realloc implementation in this blog is incorrect: the passed in pointer must not be freed if realloc is called with a non-zero length and returns NULL. This will cause a double free in correct callers.<p>As someone else pointed out, the example call of realloc is also incorrect.<p>edit: also, malloc is incorrect for three reasons: 1) sbrk doesn't return NULL on failure, 2) a large size_t length will cause a contraction in the heap segment rather than an allocation, and 3) sbrk doesn't return a pointer aligned in any particular way, whereas malloc must return a pointer suitably aligned for all types.
I fixed a crippling bug on another platform that was taking down whole servers, because someone was depending on a clever realloc to behave well.<p>This is implementation coupling at its worst. Don't do it.
This is really neat. Somehow I always assumed realloc() copied stuff instead of using the page table.<p>But say you have 4K page table size. You malloc() in turn a 2K object, a 256K object, and another 2K object, ending up with 2K, 256K, 2K in memory. Then your 256K is not aligned on a page boundary. If you realloc() the 256K it has to move since it's surrounded by two objects. When you do that, you'll wind up with the two pages on the end being mapped to multiple addresses. Which is actually just fine...Interesting...