In C the standard memory handling functions are malloc()
, realloc()
and free()
. However, C++ stdlib allocators only parallel two of them: there is no reallocation function. Of course, it would not be possible to do exactly the same as realloc()
, because simply copying memory is not appropriate for non-aggregate types. But would there be a problem with, say, this function:
bool reallocate (pointer ptr, size_type num_now, size_type num_requested);
where
ptr
is previously allocated with the same allocator for num_now
objects;num_requested
>= num_now
;and semantics as follows:
ptr
from size for num_now
objects to num_requested
objects, it does so (leaving additional memory uninitialized) and returns true
;false
.Granted, this is not very simple, but allocators, as I understand, are mostly meant for containers and containers' code is usually complicated already.
Given such a function, std::vector
, say, could grow as follows (pseudocode):
if (allocator.reallocate (buffer, capacity, new_capacity))
capacity = new_capacity; // That's all we need to do
else
... // Do the standard reallocation by using a different buffer,
// copying data and freeing the current one
Allocators that are incapable of changing memory size altogether could just implement such a function by unconditional return false;
.
Are there so few reallocation-capable allocator implementation that it wouldn't worth it to bother? Or are there some problems I overlooked?
From: http://www.sgi.com/tech/stl/alloc.html
This is probably the most questionable design decision. It would have probably been a bit more useful to provide a version of reallocate that either changed the size of the existing object without copying or returned NULL. This would have made it directly useful for objects with copy constructors. It would also have avoided unnecessary copying in cases in which the original object had not been completely filled in.
Unfortunately, this would have prohibited use of realloc from the C library. This in turn would have added complexity to many allocator implementations, and would have made interaction with memory-debugging tools more difficult. Thus we decided against this alternative.