IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Работа с динамикой, Причина ошибки?
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Делаю задачу по следующему условию:
Изображение

С того момента, как написал процедуру, которая складывает элементы очередей(например, 1 в первой ячейки очереди А, во второй Б соответственно 2, например. Я их складываю, и значения первой ячейки А, перезаписываю на результат сумму, при этом элемент Б, который использовался, освобождаю с помощью FreeMem.), FreePascal начал выдавать ошибку на указателе (знаке ^) с текстом "Internal Error 200507031", хотя вроде бы как все правильно... Может быть кто-нибудь сталкивался с такой ошибкой, и знает ее решение?

Исходный код программы приведен в аттаче.

Сообщение отредактировано: Relrin -


Прикрепленные файлы
Прикрепленный файл  din.pas ( 3.96 килобайт ) Кол-во скачиваний: 249
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Версия FPC? Настройки компилятора изменял? 2.4.2 откомпилировал и даже не поперхнулся...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Версия 2.4.0
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Обновляй.

К тому же, есть еще одно место, которое выглядит не очень хорошо (по крайней мере, у меня при запуске начались с ним проблемы). Не используй 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

программа падает. Если заменить во всей программе GetMem(X, Size) на New(X), а FreeMem(X, Size) на Dispose(X), то вылета уже не происходит...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Вылеты программы у меня наблюдается, правда она где-то зарыта в области процедуры PlusQueue
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Так. Стоп...

Ты заполнил Дек, так? Проверял, правильно ли он заполнился (т.е., правильно ли установлены указатели)? Процедура PrintDeck у тебя присутствует? Нет. Проверяй...

Дальше: разбил дек на 2 очереди. Ты проверил, правильно ли разбил? Процедура PrintQueue есть? Нет. Проверяй...

Не надо искать ошибки в последующих действиях, пока не убедился, что все предыдущие выполнены правильно. У тебя такой уверенности нет.

Потом. Вот такие конструкции a.next1^.next:=a.next1^.next^.next; с легкостью приводят к вылету программы. Если где-то будет nil или невалидный указатель. Ты опять же этого не поверяешь. Зачем тебе вообще такие многоэтажные конструкции? Что, нельзя сделать сумму очередей, не прибегая к "одноэтажной" адресации? Вот так, в смысле:
while q1 <> nil do
begin
AddToQueue (q_result, q1^.elem + q2^.elem);
q1 := q1^.next; q2 := q2^.next;
end;
? Если ты корректно разбил исходную очередь на две одинаковых по длине (зачем был приплетен Дек я тоже не понимаю, в задаче о нем нет ни слова) - то это будет прекрасно работать... Кстати, для того, чтоб разбить длинную очередь на 2 коротких, совсем не обязательно удалять значения из одной очереди и записывать их в другую. Все, что для этого нужно - это переприсвоить 4 указателя. Прописью: четыре!!! И потом можно просто работать с теми же данными, но уже не в виде очереди длиной 2*n, а в виде двух очередей длиной n каждая.

Почему работаешь через глобальные переменные - тоже не совсем понятно. Хочется глюки поотлавливать? Вот ты и занимаешься этим. Тебе удалось...

Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.04.2024 1:31
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name