ansi c struct {with dynamic array}分配给realloc的数组

时间:2010-09-24 15:42:20

标签: c

为什么以下代码给出了“双重免费或损坏”错误...当我使用gcc [(Debian 4.4.4-8)4.4.5 20100728(预发布)]编译和运行时。提前谢谢!

#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;
}

4 个答案:

答案 0 :(得分:1)

因为'a'和'one.index1'指向的存储是相同的(在第一个printf之前分配)。因此,你有一个免费的双倍。

答案 1 :(得分:1)

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

Ergo,双免费。

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

当您将指针传递给此函数时,其值(实际上是地址)将被复制到另一个本地int指针b中。 现在,当您将空间重新分配5个整数时,它会更改空间分配。所以你的空间从10个减少到5个。

根据OP的要求,获取相同的数据和单独的内存指针,必须为新指针重新分配空间,因为指针毕竟只是一个变量,持有一个地址。如果分配两个单独的块,您将获得两个单独的地址,可以单独释放。

答案 2 :(得分:0)

你正在向指针传递。您可以修改指针本身,但主函数不会获取新地址。

答案 3 :(得分:0)

这是因为您使one.index1a指向相同的内存位置。

要测试此操作,请在代码中添加以下内容:

 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.

您会注意到两个指针都会打印相同的内存地址。因此,在free(a);执行后,执行free(one.index1);是多余的,并且尝试释放未分配的资源是造成问题的原因。