2 minute read

I’d like a variant of realloc that takes the number of bytes that should be copied, in the case a copy is needed.

This doesn’t seem to be part of any allocator API I can find1, unless I missed it. It doesn’t seem to be in the common standard APIs, nor in the extended/custom APIs of the allocators I looked at, etc. It seems like low-hanging fruit, and is something I want whenever I implement a vec-style container type.

Why is this useful? Consider the following case: Let’s say a user is using the first 100 bytes of a vector with a capacity of 1000 bytes (so, size=100, capacity=1000 for this vector). The user calls v.reserve(2000) (they’re about to add that many elements or whatever). The vector implementation needs to expand its capacity, and dutifully does so using some realloc-style function. Now imagine that in this case, the allocator can’t reuse the existing storage2, and is forced to copy the allocation to new storage.

In this case, it’d be very useful for the implementation of the allocator (specifically of the realloc-style function), to know that only the first 100 bytes of the allocation are actually relevant, and not the whole 1000 bytes. But it doesn’t know that, so it has to copy all 1000 bytes, 90% of which is wasted effort.

Anyway, there’s probably some allocator out there with this, I’m just surprised that I can’t find it3. At the very least, more allocators should have this in their APIs, even if it only shows up in their extended4 APIs.

All that said, this is really just a minor gripe I’ve had for a while. For some reason this of all things overcame the inertia to become a real blog post. Hope it made sense.

P.S. I intend to push for this to be added to Rust’s allocator APIs. We could at least use it in our fallback realloc impl.

P.P.S. Okay okay, I’ll address the elephant in the room: I know I said I’d write more about Rust’s allocator API design, I still intend to, just life got in the way.

P.P.P.S. I know I halfassed this explanation, so feel free to reach out if it didn’t make sense. This post is this is just a quick note since it’s bugging me.

  1. Now that I’ve written this, I’m sure either I’ll find something with it, or someone will point out the places I’ve missed. Still. 

  2. Pretty likely that most allocators will have to copy if reallocating from 1000b to 2100b, since it’s over 2x as big, so it probably wouldn’t fit in the same size class in size-segregated allocators (Not guaranteed tho; for example, bump allocators could avoid needing the copy in some cases… either way it’s besides the point). 

  3. Note: this is different from how Rust’s grow functions take the “old size”. This is the old capacity, which would be 1000 in the example, not 100. 

  4. It’d be even better if something standardized and popular like C++ got it too, since then allocator implementors are more likely to provide it.