When you realloc for more size, it may be necessary to allocate a new block,
copy memory and deallocate the old, for example if there is not enough free
space after the original block (maybe the only example ?).
There are other possible cases. Not all allocators simply grab the
next available suitable free chunk. Some group objects into size
classes, for example, and your realloc may change which class the
object fits in.
The allocator scheme is not specified by the standard. It can be
*anything*, as long as the required semantics are preserved.
But, is it really
necessary to _copy_ bytes ? When in a virtual memory environment (off-topic
here, be I still think the question is worth), you don't access directly
physical memory, but allocated pages, so would it be possible on some
implementations, to just change page allocation ?
That *is* extending the original block.
Take the typical case: the implementation uses a linear virtual
address space for all allocated objects, and the contents of C object
pointers are addresses as used by the virtual memory manager. If an
object occupies the page at address n*pagesize, and you attempt to
extend it with realloc, then:
- There may be no page mapped at address (n+1)*pagesize, and the
implementation could request that the VMM map a new page at that
address. Aside from performing its internal housekeeping, the
realloc is done; no copying needs to take place.
- There may be a page mapped at address (n+1)*pagesize. If it's part
of some other object, then obviously the implementation cannot steal
that address for the object being resized, because pointers into the
other object will refer to that portion of the virtual address space.
The realloc'd object will have to be moved.
- Some other case may apply (eg the implementation is unable to
secure additional memory).
Some kind of immobile
trip. It could permit optimizations even when not knowing beeforehand the
exact amount of memory needed.
The malloc implementations I'm familiar with are already capable of
doing this. (Actually, for many of them it happens automatically
in many cases, via lazy allocation and copy-on-write.)
In short: yes, it's a good idea, for implementations where it's
appropriate; but it's one they typically already use.
On another off-topic note: in a large (eg 64-bit) virtual address
space, it's usually possible to space objects sparsely, so that they
nearly always can be extended this way. That's one of the advantages
of a large address space.