Reputation: 1
As I know, realloc
is supposed to make a bigger/smaller allocation and copy the data given to it here. I was making a sprisheet atlas parser and encountered this, then reproduced it with very simple code.
uint32_t* a = malloc(10 * sizeof(uint32_t));
for (uint32_t i = 0; i < 10; i++) a[i] = i;
for (uint32_t i = 0; i < 10; i++) printf("%d\n", a[i]);
printf("\n\n");
a = realloc(a, 10);
for (uint32_t i = 0; i < 10; i++) printf("%d\n", a[i]);
free(a);
The first for loop outputs 0 1 2 3 4 5 6 7 8 9
as expected, but the second one prints this 0 1 2 3 0 0 0 0 0 0
. Why has realloc zeroed out the memory for the last 6 elements? What am I doing wrong?
Upvotes: 0
Views: 78
Reputation: 53
It doesn't necessarily be 0 1 2 3 0 0 0 0 0 0
. Following is the snippet from man page of realloc.
The realloc() function shall deallocate the old object pointed to by ptr and return a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.
So, in your case only the first 10
bytes of previously allocated 10 * sizeof(uint32_t)
bytes are copied at the reallocation. Hence, while you were using second loop to print the values you were actually moving beyond 10
bytes that you are actually given or may be allowed to access using pointer a
. As a
is the pointer to uint32_t
, in each iteration, you were trying to access the items sizeof(uint32_t)
bytes further. There could be anything. Just for practical try :
for (uint32_t i = 0; i < 10; i++)
printf("%d and %p\n", *(a + i),(void*)(a+i));
You will see address is moving 4 bytes further and accessing whatever is placed there. For me output was :
0 and 0x61342d2802a0
1 and 0x61342d2802a4
2 and 0x61342d2802a8
3 and 0x61342d2802ac
4 and 0x61342d2802b0
5 and 0x61342d2802b4
6 and 0x61342d2802b8
7 and 0x61342d2802bc
8 and 0x61342d2802c0
9 and 0x61342d2802c4
I just wanted to add a minor point. Besides, @Eric has already provided sufficient answer on how reallocation
is done and handled.
Upvotes: 1
Reputation: 223776
The second parameter of realloc
is the number of bytes requested, not the number of elements. a = realloc(a, 10);
changes the allocation to 10 bytes, which is not what you want.
To change the allocation to n
elements, use a = realloc(a, n * sizeof *a);
. Or, for safety, use:
void *t = realloc(a, n * sizeof *a);
if (!t)
{
// Handle reallocation failure.
}
a = t;
The memory outside those first ten bytes has been freed (if realloc
reused the old allocation) or has not been allocated (if realloc
created a new allocation), and its contents are not defined by the C standard.
Upvotes: 2