Рекурсивное освобождение от больших попыток - PullRequest
1 голос
/ 13 февраля 2020

Я написал основную c функцию для рекурсивного освобождения структуры данных tr ie в C:

// Root pointer is passed as arg in initial call
void destroy(node *trav)
{
    for (int i = 0; i < N; i++)
    {
        if (trav->children[i])
        {
            destroy(trav->children[i]);
        }
    }

    free(trav);
}

Эта функция прекрасно работает с любым меньшим файлом словаря. Самый большой файл, который программа успешно загрузила и выгрузила, содержал 134 480 слов.

Однако он вызывает ошибку сегментации при освобождении большего значения tr ie. Файл большего размера, который вызывает ошибку сегментации, содержит 506 915 слов.

Сообщение об ошибке, выдаваемое Valgrind, гласит: «Недопустимое чтение размера 8», за которым следуют несколько обратных и наконец; "Адрес не в стеке, mallo c 'd или (недавно) free'd".

Что может быть причиной этого?

1 Ответ

1 голос
/ 13 февраля 2020

Что может быть причиной этого?

Это может быть вызвано переполнением стека, хотя это кажется несколько маловероятным: локальных почти нет, поэтому каждый кадр, вероятно, потребляет только 32 байта стека и это позволило бы рекурсию глубины 8M / 32 == 262144 с Linux стеком по умолчанию 8MiB.

Однако, если ваш tr ie крайне несбалансирован, переполнение стека возможно.

Вы можете попробовать ulimit -s unlimited и посмотреть, устранит ли это проблему go.

Или вы можете запустить свою программу под GDB и изучить инструкцию, по которой сообщается SIGSEGV. Если это CALL, PUSH или другая форма «перемещения в стек», переполнение стека также весьма вероятно.

...