Возможная проблема free () в моем алгоритме Дейкстры

#c #windows-vista

#c #windows-vista

Вопрос:

Я использую алгоритм Дейкстры, чтобы найти кратчайший путь для завершения определенной головоломки, где головоломка работает следующим образом. У вас есть пять шифров, которые могут быть где угодно от -4 до 4 (хотя они представлены по-разному, как «очень низкий / высокий» для -4 / 4, «низкий / высокий» для -3 до -1 или от 1 до 3 и «завершено» для 0). Цель состоит в том, чтобы присвоить всем пяти значение 0, используя 20 различных «методов», которые повышают / понижают значения cypher на заданную величину. Если метод модифицирует один из шифров за пределами границ, то есть выше 4 или ниже -4, то вместо этого он ничего не делает. Итак, я представил это в виде графика, где узлами являются все возможные комбинации значений шифрования, а начальным узлом является завершенный узел (0,0,0,0,0). Чтобы упростить задачу, я представляю шифры в виде значений от 0 до 8, причем 4 является завершенным значением — это позволяет мне преобразовать их по основанию 9 в индексы массива графика, так что не нужно тратить время на поиск.

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

Я не задавал здесь никаких вопросов раньше, поэтому я не знаю этикета — я собираюсь поместить сюда весь исходный код, потому что я не знаю, что уместно, а что нет в данной конкретной ситуации, но это около 140 строк, что довольно много. При дальнейшем прочтении оказывается, что на самом деле нет тега или чего-то еще, поэтому я просто пока добавлю его в codepad.

http://codepad.org/I0K0ETsU

Редактировать: Хорошо. Хорошо. Теперь я окончательно запутался. Я решил просто прокомментировать это, для смеха — и больше ничего не пойдет не так. Он завершается, выдает output.txt и текстовый файл выглядит совершенно правильным. Я не могу понять, что, черт возьми, не так с кодом, из-за чего он разваливается при использовании free(), когда больше ничего не происходит неправильно.

Комментарии:

1. Windows просто отключает его, сообщая «Проблема привела к тому, что программа перестала корректно работать».

Ответ №1:

После беглого просмотра, похоже, что pool-> next инициализируется в temp, и в это время temp-> next неинициализируется. Итак, когда вы переходите по списку к temp-> next и пытаетесь освободить его, вы освобождаете неинициализированный указатель (или память, которой вы не владеете).

Комментарии:

1. Он не должен пытаться освободить temp-> next, если temp-> next неинициализирован (я не думаю) — значение пула корневых элементов равно общему количеству элементов в связанном списке, поэтому обход связанного списка не выходит за пределы границы неинициализированного указателя.

Ответ №2:

free Обычно происходит сбой только по нескольким причинам:

  • Пытаюсь освободить нулевой указатель
  • Пытаюсь освободить что-то, что было освобождено раньше (двойное освобождение)
  • Попытка освободить что-то недопустимое (т. Е. освободить адрес, который является мусором)
  • Повреждение памяти (область, в которой хранится информация о выделенном разделе, была переполнена)

Комментарии:

1. Просто обратите внимание, что на самом деле абсолютно безопасно вызывать free по нулевому указателю.

2. man 3p free : Если ptr является нулевым указателем, никаких действий не должно выполняться. Хороший звонок, сэр.

Ответ №3:

Оказывается, проблема заключалась в том, что я не включил символ 0 в параметр длины строки для malloc().