开发者

ansi c struct {with dynamic array} assigned to array which is realloc

开发者 https://www.devze.com 2023-01-18 00:03 出处:网络
why the below code gives me error of \"double free or corruption\"... when i compi开发者_高级运维le and run with gcc [(Debian 4.4.4-8) 4.4.5 20100728 (prerelease)]. Thanks in advance!

why the below code gives me error of "double free or corruption"... when i compi开发者_高级运维le and run with gcc [(Debian 4.4.4-8) 4.4.5 20100728 (prerelease)]. Thanks in advance!

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
 int *index1;
} data;

void doo(int *);

int main(int argc, char *argv[])
{
 int *a = (int *) malloc(10*sizeof(int));
 int i;

 for(i=0; i<10; i++)
 {
  a[i] = 2*i;
 }

 doo(a);

 data one;
 one.index1 = a;

 printf("%d\n", one.index1[4]);

 free(a);

 printf("%d\n", one.index1[4]);

 free(one.index1);
 return 0;
}

void doo(int *b)
{
 b = (int *) realloc(b, 5*sizeof(int));
 return;
}


one.index1=a;
...
free(a);
...
free(one.index1);
...

Ergo, the double free.

void doo(int *b)
{
 b = (int *) realloc(b, 5*sizeof(int));
 return;
}

When you pass the a pointer to this function, its value(which is infact an address), gets copied into b, another local int pointer. Now, when you realloc space for 5 ints, it changes the space allocation for a infact. So your space gets reduced from 10 to 5 ints.

As requested by OP, to get the same data & separate memory pointers, space must be allocated afresh for the new pointer, as a pointer is after all, just a variable, holding an address. If you allocate two separate blocks, you would get two separate addresses, which can be freed individually.


Because the storage pointed to by 'a' and 'one.index1' are the same (assignment before the first printf). Thus you have a double free.


You are passing to doo a pointer. You modify the pointer itself, but your main function does not get the new address.


That happens because you make one.index1 and a point to the same memory location.

To test this add the following to your code:

 one.index1 = a; // from now on, both variables point to the same address

 printf("-> 0x%x\n", one.index1);
 printf("-> 0x%x\n", a);

 printf("%d\n", one.index1[4]);

 free(a); // release the resource pointed by a

 // You should not try to print the data of one.index1[4] since 
 // that piece of memory doesn't exist no more. 
 printf("%d\n", one.index1[4]); 

 free(one.index1); // Problem: trying to free the same memory resource TWICE.

You'll notice that both pointers will print the same memory addresses. So after free(a); is executed, performing free(one.index1); is redundant, and trying to free a resource that is not allocated anymore is what is causes the problem.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号