Случайный сбой malloc? - PullRequest
       30

Случайный сбой malloc?

1 голос
/ 27 апреля 2011

Я пытаюсь прочитать двоичный файл, в котором есть блоки, начинающиеся с идентификатора (например, файл 3DS).Я перебираю файл и с помощью переключателя программа определяет, какой идентификатор имеет блок, а затем считывает данные в структуру файла.Иногда мне нужно использовать malloc для выделения памяти для данных динамического размера.Во время чтения коммутатор часто проходит через тот же случай, когда ему выделяется память, но в определенный момент в файле он падает на тот же самый malloc.Файл, который я хочу прочитать, составляет около 1 МБ.Но когда я пытаюсь запустить программу с другим файлом размером около 10 КБ и той же структурой, она успешно читает его.

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


Код ошибки, который я получаюкогда отладка:

Heap corruption detected at 0441F080
HEAP[prog.exe]: HEAP: Free Heap block 441f078 modified at 441f088 after it was freed

Также, когда я выполняю ее в режиме отладки, по какой-то причине я могу прочитать больше данных из файла.Программа живет дольше, прежде чем падает.


Вот фрагмент кода, в котором происходит сбой:

switch (id) {
    case 0x62:
    case 0x63:
    // ...
        {
            char n_vertices = id - 0x60 + 1;// just how I calculate the n_vertices from the block ID
            fread(&mem.blocks[i].data.attr_6n.height, 2, 1, f);
            mem.blocks[i].data.attr_6n.vertices = malloc(2 * n_vertices);// crash
            for (short k = 0; k < n_vertices; k++) {
                fread(&mem.blocks[i].data.attr_6n.vertices[k], 2, 1, f);// read shorts
            }
        }
        break;
    // ...
}

Ответы [ 3 ]

8 голосов
/ 27 апреля 2011

Возможно, у вас поврежденная куча.Это может быть вызвано недействительными освобождениями (освобождение ненужной или уже свободной памяти) или некоторой случайной порцией кода, записываемого за пределы его области памяти, в место, где хранятся структуры данных поддержки кучи.Скорее всего, это будет фрагмент кода, который не имеет ничего общего с этой динамически выделяемой памятью.

Отслеживание ошибок, как это настоящий медведь.Они появляются долго после того, как испорченный код был выполнен, и имеют раздражающую тенденцию превращаться в heisenbugs (ошибки, которые перемещаются или исчезают при попытке их отладки).

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

Просматривая код, который вы только что опубликовали, одну вещь, которую я бы весьма предложилвам нужно убедиться, что ваша malloc указала достаточно памяти для хранения всех данных, которые вы пытаетесь загрузить в нее.Мне кажется, что вы принимаете 2 байта для каждой вершины.Это кажется мне немного подозрительным.Я не знаю ваш код, но 4 или 8 были бы гораздо более распространенными размерами элементов, чтобы увидеть там.Несмотря на это, отраслевая практика заключается в том, чтобы использовать sizeof() для целевого типа, чтобы убедиться, что вы правильно поняли.

Другой вариант, если ваше сообщение отладчика может показать вам, где оно происходит, было бы поставитьНаблюдайте за точкой отладчика (или напишите некоторый код наблюдения ... или вручную выгрузите и осмотрите область) при входе в отладчик, чтобы попытаться выяснить, какая строка кода нарушена.

Удачи.Я ненавижу этих ошибок.

3 голосов
/ 27 апреля 2011

Скорее всего, куча каким-то образом повреждена, сбой malloc, например, попытка просмотреть поврежденный связанный список свободных блоков (или похожую структуру, я не совсем уверен, что сегодня используется в современных распределителях кучи).

Убедитесь, что ваш код не записывается после конца выделенного блока.

0 голосов
/ 27 апреля 2011

Вам нужно запустить это в отладчике памяти, как valgrind. Поскольку похоже, что вы работаете в Windows, посмотрите следующее: Есть ли хороший заменитель Valgrind для Windows?

...