Повреждение Realloc после некоторой итерации C

Я пытаюсь динамически выделить память для массива указателя структуры в функции. Он работает до 3-х итераций, но вылетает с этой ошибкой:

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, то я получаю ошибку.

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

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

2 ответа

Решение

В этом вызове функции

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

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

Другие вопросы по тегам