С того момента, как написал процедуру, которая складывает элементы очередей(например, 1 в первой ячейки очереди А, во второй Б соответственно 2, например. Я их складываю, и значения первой ячейки А, перезаписываю на результат сумму, при этом элемент Б, который использовался, освобождаю с помощью FreeMem.), FreePascal начал выдавать ошибку на указателе (знаке ^) с текстом "Internal Error 200507031", хотя вроде бы как все правильно... Может быть кто-нибудь сталкивался с такой ошибкой, и знает ее решение?
Исходный код программы приведен в аттаче.
volvo
10.04.2011 16:34
Версия FPC? Настройки компилятора изменял? 2.4.2 откомпилировал и даже не поперхнулся...
Relrin
10.04.2011 16:41
Версия 2.4.0
volvo
10.04.2011 16:52
Обновляй.
К тому же, есть еще одно место, которое выглядит не очень хорошо (по крайней мере, у меня при запуске начались с ним проблемы). Не используй GetMem/FreeMem, работай с New/Dispose. Вот тут (процедура DivisionDeck):
{перенос части в очередь а}if i<=5thenbegin{переносим в ячейку число (очередь а) из дека}
a.next1^.elem:=c.front^.elem;
{запоминаем ссылку дека}
adr:=c.front^.next;
{переходим к следующей ссылке дека}
c.front^.next:=c.front^.next^.next;
{освобождаем память предыдущей ячейки, т.к. использовалии ее}{и она нам больше не потребуется в дальнейшем}{*} FreeMem(adr,SizeOf(adr));
{выделяем память для нового элемента очереди а}
GetMem(a.next1^.next,sizeof(a.next1^.next));
{заносим в нее ссылку}
a.next1^.next:=a.next1^.next^.next;
end
программа падает. Если заменить во всей программе GetMem(X, Size) на New(X), а FreeMem(X, Size) на Dispose(X), то вылета уже не происходит...
Relrin
10.04.2011 17:14
Вылеты программы у меня наблюдается, правда она где-то зарыта в области процедуры PlusQueue
volvo
10.04.2011 17:44
Так. Стоп...
Ты заполнил Дек, так? Проверял, правильно ли он заполнился (т.е., правильно ли установлены указатели)? Процедура PrintDeck у тебя присутствует? Нет. Проверяй...
Дальше: разбил дек на 2 очереди. Ты проверил, правильно ли разбил? Процедура PrintQueue есть? Нет. Проверяй...
Не надо искать ошибки в последующих действиях, пока не убедился, что все предыдущие выполнены правильно. У тебя такой уверенности нет.
Потом. Вот такие конструкции a.next1^.next:=a.next1^.next^.next; с легкостью приводят к вылету программы. Если где-то будет nil или невалидный указатель. Ты опять же этого не поверяешь. Зачем тебе вообще такие многоэтажные конструкции? Что, нельзя сделать сумму очередей, не прибегая к "одноэтажной" адресации? Вот так, в смысле:
? Если ты корректно разбил исходную очередь на две одинаковых по длине (зачем был приплетен Дек я тоже не понимаю, в задаче о нем нет ни слова) - то это будет прекрасно работать... Кстати, для того, чтоб разбить длинную очередь на 2 коротких, совсем не обязательно удалять значения из одной очереди и записывать их в другую. Все, что для этого нужно - это переприсвоить 4 указателя. Прописью: четыре!!! И потом можно просто работать с теми же данными, но уже не в виде очереди длиной 2*n, а в виде двух очередей длиной n каждая.
Почему работаешь через глобальные переменные - тоже не совсем понятно. Хочется глюки поотлавливать? Вот ты и занимаешься этим. Тебе удалось...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.