ANSI C struct {с динамическим массивом} назначен массиву, который является realloc - PullRequest
1 голос
/ 24 сентября 2010

почему приведенный ниже код выдаёт мне ошибку "double free or коррупция" ... когда я компилирую и запускаю с gcc [(Debian 4.4.4-8) 4.4.5 20100728 (prerelease)] Заранее спасибо!

#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 ]

1 голос
/ 24 сентября 2010
one.index1=a;
...
free(a);
...
free(one.index1);
...

Ergo, double free.

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

Когда вы передаете указатель на эту функцию, ее значение (которое является адресом) копируется в b, другой локальный указатель int,Теперь, когда вы перераспределяете пространство на 5 дюймов, оно меняет распределение пространства для заражения.Таким образом, ваше пространство уменьшается с 10 до 5 дюймов.

В соответствии с запросом OP, чтобы получить те же данные и отдельные указатели памяти, пространство должно быть выделено заново для нового указателя, так как указатель, в конце концов, простопеременная, содержащая адрес.Если вы выделите два отдельных блока, вы получите два отдельных адреса, которые могут быть освобождены по отдельности.

1 голос
/ 24 сентября 2010

Поскольку хранилище, на которое указывают 'a' и 'one.index1', одинаково (присваивание перед первым printf). Таким образом, у вас есть двойной бесплатный.

0 голосов
/ 24 сентября 2010

Это происходит потому, что вы заставляете one.index1 и a указывать на одну и ту же ячейку памяти.

Чтобы проверить это, добавьте в свой код следующее:

 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); является избыточным, и попытка освободить ресурс, который больше не выделяется, является причиной проблемы.

0 голосов
/ 24 сентября 2010

Вы передаете doo указатель.Вы изменяете сам указатель, но ваша основная функция не получает новый адрес.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...