Reputation:
I thought that realloc()
function reallocates the memory and doesn't change it.
After debugging an assignment that I had to do I realized that realloc() changed some elements in the memory and created bugs.
So I wrote the following code:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *a, *p;
a = (int*)calloc(10, sizeof(int));
for (int i = 0;i < 10; i++)
a[i] = i;
for (int i = 0; i < 10; i++)
printf("%d ", a[i]);
printf("\n");
p = realloc(a, 20);
p[10] = 10;
for (int i = 0; i < 11; i++)
printf("%d ", p[i]);
printf("\n");
for (int i = 0; i < 10; i++)
printf("%d ", a[i]);
return 0;
}
and I got the following output
Could anybody explain why would this happen?
I tried using malloc()
instead of calloc()
but the existing array would also change.
Upvotes: 1
Views: 807
Reputation: 11921
the statement a = (int*)calloc(10, sizeof(int));
allocates 10x4
i.e 40
bytes. lets say from 0x100
to 0x140
location.
-----------------------------------------
| | | | | | | | |
-----------------------------------------
0x100 .. 0x120 0x140
a
next when you do realloc()
on same a
like p = realloc(a, 20);
it won't add 20
bytes, it reduces whole memory to 20
bytes itself i.e from 0x100
to 0x120
and now when you access p[10] = 10;
its out of bound i.e you are trying to put data in around 0x140
location which result in undefined behavior.
--------------------
| | | |
--------------------
0x100 .. 0x120
a
p
from the man 3 realloc
The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old size, the added memory will not be initialized.
If you really want to expand existing memory by 20
bytes then do like
p = realloc(a ,20*sizeof(int));
Upvotes: 0
Reputation: 3234
p = realloc(a, 20);
In this statement, you are reallocating the p to 20/4 = 5.
Accessing undefined memory leads to undefined behavior
. This means that compiler can behave any way: program crash, garbage value, sometimes correct results.
That's why you are getting garbage values after 5th element.
Edit it to: p = realloc(a, 20*sizeof(int));
Upvotes: 0
Reputation: 8013
From cppreference
The reallocation is done by either:
a) expanding or contracting the existing area pointed to by ptr, if possible. The contents of the area remain unchanged up to the lesser of the new and old sizes. If the area is expanded, the contents of the new part of the array are undefined.
b) allocating a new memory block of size new_size bytes, copying memory area with size equal the lesser of the new and the old sizes, and freeing the old block.
It depends on the implementation of the compiler and the size you're reallocating. If the newly allocated size is not occupi-able without fragment, then the realloc will definitely going to allocate memory in different location, which is more efficient than freeing already used up memory.
Upvotes: 1
Reputation: 726479
This happens because you've re-allocated fewer items than originally allocated with calloc
. The confusion is due to a slight difference in signatures of calloc
and malloc
/realloc
. The call
a = calloc(10, sizeof(int));
allocates 10 blocks of sizeof(int)
, or 40 bytes on systems with sizeof(int)
equal to 4, while
p = realloc(a, 20);
asks to reduce the size of that block to 20 bytes. In other words, calloc
does multiplication by sizeof
for you, while realloc
and malloc
require you to do multiplication yourself.
Once you told realloc
that you want only 20 bytes, any access past the end of the fifth integer is undefined behavior.
If you want to extend the size to 20 int
s, multiply by sizeof(int)
:
p = realloc(a, 20*sizeof(int));
Upvotes: 2