Делаю задачу по следующему условию:
С того момента, как написал процедуру, которая складывает элементы очередей(например, 1 в первой ячейки очереди А, во второй Б соответственно 2, например. Я их складываю, и значения первой ячейки А, перезаписываю на результат сумму, при этом элемент Б, который использовался, освобождаю с помощью FreeMem.), FreePascal начал выдавать ошибку на указателе (знаке ^) с текстом "Internal Error 200507031", хотя вроде бы как все правильно... Может быть кто-нибудь сталкивался с такой ошибкой, и знает ее решение?
Исходный код программы приведен в аттаче.
Прикрепленные файлы
din.pas ( 3.96 килобайт )
Кол-во скачиваний: 250
Версия FPC? Настройки компилятора изменял? 2.4.2 откомпилировал и даже не поперхнулся...
Версия 2.4.0
Обновляй.
К тому же, есть еще одно место, которое выглядит не очень хорошо (по крайней мере, у меня при запуске начались с ним проблемы). Не используй GetMem/FreeMem, работай с New/Dispose. Вот тут (процедура DivisionDeck):
{перенос части в очередь а}
if i<=5 then
begin
{переносим в ячейку число (очередь а) из дека}
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
Вылеты программы у меня наблюдается, правда она где-то зарыта в области процедуры PlusQueue
Так. Стоп...
Ты заполнил Дек, так? Проверял, правильно ли он заполнился (т.е., правильно ли установлены указатели)? Процедура PrintDeck у тебя присутствует? Нет. Проверяй...
Дальше: разбил дек на 2 очереди. Ты проверил, правильно ли разбил? Процедура PrintQueue есть? Нет. Проверяй...
Не надо искать ошибки в последующих действиях, пока не убедился, что все предыдущие выполнены правильно. У тебя такой уверенности нет.
Потом. Вот такие конструкции a.next1^.next:=a.next1^.next^.next; с легкостью приводят к вылету программы. Если где-то будет nil или невалидный указатель. Ты опять же этого не поверяешь. Зачем тебе вообще такие многоэтажные конструкции? Что, нельзя сделать сумму очередей, не прибегая к "одноэтажной" адресации? Вот так, в смысле:
while q1 <> nil do? Если ты корректно разбил исходную очередь на две одинаковых по длине (зачем был приплетен Дек я тоже не понимаю, в задаче о нем нет ни слова) - то это будет прекрасно работать... Кстати, для того, чтоб разбить длинную очередь на 2 коротких, совсем не обязательно удалять значения из одной очереди и записывать их в другую. Все, что для этого нужно - это переприсвоить 4 указателя. Прописью: четыре!!! И потом можно просто работать с теми же данными, но уже не в виде очереди длиной 2*n, а в виде двух очередей длиной n каждая.
begin
AddToQueue (q_result, q1^.elem + q2^.elem);
q1 := q1^.next; q2 := q2^.next;
end;