In malloc-ng, does realloc to a smaller size return a different pointer? (If you want to be pedantic I am asking about returning a pointer with a different representation, provenance is always different but I'm not asking about that .)
Conversation
The question I was really interested in was whether realloc to a smaller size can return NULL, and I thought that the answer to that was so clearly “obviously not” that I didn't dare ask it, but it seems it is a situation that can arise?
3
1
3
Since even munmap can fail, realloc to a smaller size can fail for large allocations in any allocator. It's up to them if they report it, but I expect most report it.
Most modern allocators use slab allocation. If the size class changes, they need to allocate and copy to that.
2
1
Most modern allocators like jemalloc, mimalloc, hardened_malloc and others use slab allocation with a single size class per slab. They're called runs in jemalloc but it's essentially the same concept. I think musl is a bit more flexible to save space but it still largely applies.
1
Even for a dlmalloc-style allocator with everything mixed together, it still has a distinction between allocations managed via free lists within larger regions and allocations mapped as their own regions. In general, it is always possible for shrink to fail when this happens.
1
I think might be asking "in practice" because a realloc could detect that failure, and just return the original pointer untouched.
1
It normally wouldn't have a separate code path for shrinking and expanding because it's the same thing with a different copy size. It could special case the error path to essentially leak memory without telling the caller but I don't really expect any malloc implementation does.
1
2
Reporting the error allows the caller to attempt to free memory elsewhere and try again.
Part of handling malloc errors is wrapping it and adding code to clear caches, etc. before actually bubbling it up to be handled by the calling code.
C could standardize an API for this.
1
C++ has en.cppreference.com/w/cpp/memory/n.
Since C doesn't have an API for this, you really do need it to bubble up the error for this realloc case or you're missing an opportunity to avoid leaking. At the very least you probably want to log it. You're about to get more OOM errors anyway.
If you can't allocate a new VMA to shrink a large allocation and can't allocate a new slab (if necessary) to shrink a small allocation, the program has a serious out-of-memory situation to handle. Leaking memory you tried to release is really not a good thing to have happen then.
1
1
In that kind of situation, you probably want to call malloc_trim() if available and then do stuff like dropping caches, iterating over as many vectors, etc. as possible and calling APIs like shrink_to_fit and so on before you even bubble up the error from your malloc wrappers.
1
Show replies


