#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.
Редактировать: Хорошо. Хорошо. Теперь я окончательно запутался. Я решил просто прокомментировать это, для смеха — и больше ничего не пойдет не так. Он завершается, выдает 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().