Вызов free () для 2D-массива приводит к seg. придираться - PullRequest
3 голосов
/ 07 января 2012

Я пытаюсь выучить C, и я дошел до того, что мне захотелось попробовать что-то более продвинутое, чем небольшие и простые примеры печати текста на консоль, очень просто использовать указатели и т. Д.

Проблема в том, что моя программа зависает при моем вызове free, и я уверен, что это указатель (и) каким-то образом преследует меня ...

Итак, я создал двумерныймассив выглядит так:

bool InitializeGrid(struct Grid *g, int rows, int columns)
{
    g->rows = rows;
    g->columns = columns;
    g->grid = malloc(g->rows * sizeof(int *));

    if(g->grid == NULL)
    {
        printf("Could not allocate memory for grid rows.\n");
        return false;
    }

    for (int i = 0; i < g->rows; i++)
    {
        g->grid[i] = malloc(g->columns * sizeof(int));

        if(g->grid[i] == NULL)
        {
            printf("Could not allocate memory for grid columns.\n");
            return false;
        }
    }

    / ... /

    return true;
}

Структура Grid выглядит следующим образом:

struct Grid
{
    int rows;
    int columns;
    int **grid;
};

Затем я успешно использую сетку во всей программе, и все отлично работает.Когда программа собирается выйти, мне нужно / я хочу освободить память, которую я выделил.Вот как я это делаю:

void CleanupGrid(struct Grid *g)
{
    for(int i = 0; i < g->rows; i++)
        free(g->grid[i]);

    free(g->grid);
}

Но на первом свободном (g-> grid [i]) я получаю ошибку сегментации.

Почему это не работает?Как я могу это исправить?

Редактировать:

stdbool.h был включен в программу для использования bool / true / false.

Я чувствую себя действительно глупо, когда смотрювслепую в заявлении free ().Когда я уменьшаю программу до абсолютного минимума, она прекрасно работает с операторами free ().Когда я в один момент обращаюсь к сетке и пишу ей, free () приветствует меня ошибкой сегментации.

Принятие ответа user1083265.

1 Ответ

3 голосов
/ 07 января 2012

Я компилирую ваш код (просто alloc / dealloc), и он не падает.

Возможно, при использовании выделенной сетки вы повредите часть памяти над выделенными фрагментами. Glibc использует канарские значения для обнаружения такого повреждения - поэтому вы получаете segfault при освобождении поврежденной памяти.

...