I am trying to reallocate memory using realloc in the below program and checking after realloc initial memory which i was reacted using malloc(i = (int*)malloc(5 * sizeof(int))) still exist or not, using below program i am able to access the data after realoc i have checked by using another pointer (i.e *m). is this proper behavior ? or memory should be free once realloc called?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *i,*jn, *m;
i = (int*)malloc(5 * sizeof(int));
int j,k=10;
for(j=0 ;j<5; j++)
{
i[j] = j;
printf("%d \n",i[j]);
}
for(j=0 ;j<5; j++)
{
printf("%p\n",i++);
}
jn = (int *)calloc(5, sizeof(*i));
for(j=0 ;j<5; j++)
{
printf("%p\n",jn++);
}
i = i-5;
m = i;
printf("m = %p %d\n",(m+1), *(m+1));
i =(int *)realloc(i,8*sizeof(int));
for(j=0 ;j<8; j++)
{
printf("%d\n",i[j]);
}
for(j=0 ;j<8; j++)
{
printf("%p\n",i++);
}
printf("m = %p %d\n",(m+1), *(m+1));
return 0;
}
Firstly, realloc might decide to
Allocate a new memory block, copy data, and free the original one, or
Simply expand/contract the original block "in place" without allocating the new one.
Which approach it will choose depends on the implementation and various other external factors. It might follow the first approach. Or it might follow the second approach. You can easily figure out which approach it followed by comparing the values of pointers i and m after realloc.
Secondly, if realloc decided to follow the first approach (i.e. allocate a new memory block), then the old block is indeed freed by realloc. In that case trying to access the original memory location leads to undefined behavior.
If realloc decided to follow the second approach (i.e. expand or shrink the original memory block "in place"), then m and i will keep pointing to the same location. In that case there's no surprise in seeing the same data through m.
P.S. This means that the behavior of your code is either trivial or undefined. It can't really be used to analyze whether the behavior is "proper". What did your expect to happen if the memory was indeed freed?
realloc is equivalent to:
void *
realloc(void *old, size_t newsz)
{
size_t old_sz = internal_function_that_finds_old_size(old);
void *new = malloc(newsz);
if (new == NULL)
return NULL;
memcpy(new, old, oldsz);
free(old);
return new;
}
realloc can do something more efficient including not changing the pointer and just making the size allocated bigger, it can use kernel facilities to map the memory somewhere else to avoid the copy, etc. But in general realloc should be treated as doing exactly what I wrote above because that is the worst case behavior.
Now, when it comes to your program. You're touching memory through invalid pointers, anything can happen. m stops being a valid pointer after the call to realloc. It doesn't mean that anyone will stop you from using it, it just means that if you do use it your program is no longer guaranteed to do anything sensible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With