2017-02-13 19 views
1

Я пытаюсь динамически выделять память для массива struct pointer в функции. Он работает до 3 итерации, но аварии после того, как с этой ошибкой:Повреждение Realloc после некоторой итерации C

double free or corruption (fasttop): ... 

Вот моя структура декларации массив указателей:

Intersection** alreadyUse = malloc(sizeof(Intersection*)); 

if(alreadyUse == NULL) { 
    exit(1); 
} 

int size = 1; 
alreadyUse[0] = inter; // Pointer of an Intersection 

// Some Code 

checkFunction(alreadyUse, &size, interLeft); 

И это моя функция

bool checkFunction(Intersection** alreadyUse, int* size, Intersection* inter) { 

    for(int i = 0; i < *size; i++) { 
     if(alreadyUse[i] == inter) { 
      return true; 
     } 
    } 

    *size = *size +1; 
    Intersection** tmp = realloc(alreadyUse, sizeof(Intersection*) * *size); 

    if(tmp == NULL){ 
     exit(1); 
    } 
    else { 
     alreadyUse = tmp; 
    } 

    alreadyUse[*size-1] = inter; 

    return false; 
} 

Как я уже сказал, он работает на 1, 2, 3, тогда я получаю ошибку.

Есть ли у кого-то идея, почему это работает, а затем внезапно сбой?

Спасибо за помощь.

+1

Мы не знаем тип пересечения –

ответ

1

В этой функции вызова

checkFunction(alreadyUse, &size, interLeft); 

переменной size передается по ссылке. Поэтому он может быть изменен в функции. Однако, как вы видите, переменная alreadyUse не передается по ссылке. Таким образом, функция имеет дело с копией значения переменной. Если вы хотите, что переменная будет изменен в функции вы должны передать его по ссылке

checkFunction(&alreadyUse, &size, interLeft); 
       ^^^^^^^^^^^ 

Таким образом, функция должна быть объявлена ​​как

bool checkFunction(Intersection*** alreadyUse, int* size, Intersection* inter); 
        ^^^^^^^^^^^^^^^ 

Определение функции может выглядеть

bool checkFunction(Intersection ***alreadyUse, int *size, Intersection *inter) 
{ 
    for (int i = 0; i < *size; i++) 
    { 
     if (alreadyUse[0][i] == inter) return true; 
    } 

    Intersection **tmp = realloc(alreadyUse[0], sizeof(Intersection *) * (*size + 1)); 

    if (tmp == NULL) exit(1); 

    alreadyUse[0] = tmp; 

    alreadyUse[0][(*size)++] = inter; 

    return false; 
} 
+0

Говоря «размер» передается по ссылке «запутанно и неточно, поскольку C - это чисто проход по языку значений. Указатель на 'size' передается по значению. –

+1

@DavidSchwartz Термин по ссылке действителен и точен в C Например, «Тип указателя описывает объект, значение которого предоставляет ссылку на объект ссылочного типа». –

+0

Возможно: «... a_reference_ to' size' передано ... » – chux

4

Вы меняете значение alreadyUse внутри checkFunction. Но это не влияет на вызывающего. Если вызов realloc действительно перераспределяется, у вызывающего абонента все еще есть указатель на старый блок, который был освобожден.