That's a dubious assumption. There are allocation schemes which
over-allocate areas (typically rounding them up to a power of two);
realloc under such a scheme might well be able to simply extend the
"in use" portion of the block in many cases.
In some implementations, allocated blocks might be scattered through
a large virtual memory space such that they can be trivially extended.
In short, you *don't know* what realloc does.
I just did an experiment. I wrote a small program that initially sets
a pointer to the result of malloc(1), then repeatedly sets to the
result of realloc with successively larger values (1, 2, 3, ...).
When I iterate from 1 to 1000000, the pointer value only changes a few
times for small values. On one implementation, the value changes only
when realloc() is called with a size of 13; on another, it changes at
9, 17, 25, and 33. For all other sizes, all the way up to a megabyte,
it just extends the existing region of memory; presumably no copying
is done.
If I add a call to malloc(1) before each realloc() (with no
corresponding free()), the pointer value changes much more often on
one implementation, but not on the other. Probably the small
allocation is (at least sometimes) done just after the existing block,
preventing it from being expanded; on the other implementation, it
looks like the small allocation happens to be done just *before* the
existing block, allowing it to expand.
All this is, of course, extremely system-specific. Michael is quite
correct: you *don't know* what realloc does.
Here's the program. One caveat: the "ptr != prev" comparison probably
invokes undefined behavior when realloc() moves the memory block and
ptr becomes invalid.
It takes a command-line argument to specify the number of iterations,
defaulting to 1024. The "-d" option tells it to do the dummy malloc()
call. There's little or no error checking.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
void *ptr = malloc(1);
void *prev = ptr;
size_t bytes;
size_t max = 1024;
void *dummy;
int malloc_dummy = 0;
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv
, "-d") == 0) {
malloc_dummy = 1;
}
else if (strcmp(argv, "-h") == 0) {
printf("Usage: %s [-h] [-d] [count\n");
exit(EXIT_FAILURE);
}
else {
max = atol(argv);
}
}
printf("Iterating from 1 to %ld\n", (long)max);
printf("malloc(1) --> [%p]\n", ptr);
for (bytes = 1; bytes <= max; bytes ++) {
if (malloc_dummy) {
dummy = malloc(1);
}
ptr = realloc(ptr, bytes);
if (ptr != prev) {
printf("realloc(%ld) --> [%p]\n", (long)bytes, ptr);
prev = ptr;
}
}
return 0;
}