Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

Ошибка при удалении обьекта. Delphi

Привет ALL!
Имееться класс:
TLPoint=class (Tlabel)
public
a,b:double;
l:Tlist;
. . .
constructor Create(com:Tcomponent); override;
destructor Destroy;
. . .
end;
constructor TLPoint.Create(com:Tcomponent);
begin
inherited create(com);
bmp:=Tbitmap.Create;
l:=Tlist.Create;
end;
destructor TLPoint.Destroy;
var
i:integer;
begin
inherited Destroy;
bmp.Free;
for i:= 0 to l.Count-1 do
FreeMem(l.Items[i]);
l.Destroy;
end;
В самой программе выполняеться что-то вроде:
var
ListP:Tlist; {Глобальная, в модуле Unit1}
procedure ADD; {Unit1}
var
Lpoint:TLpoint;
begin
Lpoint:=Tlpoint.create(self);
Lpoint.Parant:=form1;
....
ListP.add(Lpoint);
end;
procedure ADD; {Unit2}
var
Lpoint:TLpoint;
begin
Lpoint:=Tlpoint.create(self);
Lpoint.Parant:=form2;
....
ListP.add(Lpoint);
end;
procedure Tform1.DestroyForm(sender:Tobject);
var
i:integer;
begin
for i:= 0 to listP.Count-1 do
begin
TlPoint(listP.Items[i]).Destroy;
end;
listP.Free;
end;
Так вот, если все обьекты созданны и добавленны в Unit1, то всё работает как
надо!!!
Но вот если, хоть один обьект TlPoint создан и добавлен из другого модуля,
то при уничтожении выскакивает куча ошибок обращения к памяти?!
--
В процесси работы пре обращении к обьектам из списка тоже без ошибок
(TlPoint(listP.Items[i].color:=clBlack).
--
Если убрать код Tlpoint.Destroy, то тоже всё ок.
Я вот думаю, моджет вообще обьекты по окончанию работы программы не
уничтожать?
Я слышал, что форточка сама память очистить в состоянии?

Номер выпуска : 3916
Возраст листа : 476 (дней)
Количество подписчиков : 517
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/294131
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

-*Информационный канал Subscribe.Ru
Подписан адрес:
Код этой рассылки: comp.soft.prog.prog
Написать в лист: mailto:comp.soft.prog.prog-list@subscribe.ru
Отписаться: mailto:comp.soft.prog.prog--unsub@subscribe.ru?subject=comp.soft.prog.prog

http://subscribe.ru/ http://subscribe.ru/feedback

Ответить   Mon, 10 Jan 2005 17:10:58 +0300 (#294131)

 

Ответы:

Hello Малышев,

Monday, January 10, 2005, 4:10:58 PM, you wrote:

как

Мне кажется, что-то не так в самом деструкторе списка и наверное в
обработчике уничтожения формы (то есть, в двух последних методах,
которые я оставил в теле письма). Непонятно, почему используется цикл

в деструкторе списка. Разве просто l.Free недостаточно? Тем более, при
создании списка не употреблялось GetMem.
И в DestroyForm тоже сомнителен цикл

По крайней мере, здесь-то уж точно деструктор явно не должен
вызываться.

А что касается самоочистки, то да - есть такое дело. По идее, по
закрытии главного окна приложения, все указатели этого приложения
освобождаются. Но на это можно положиться, если в приложении по ходу
дела не придется перестраевать список.

Ответить   Вадим Шешунов Mon, 10 Jan 2005 18:55:57 +0200 (#294246)

 

Здравствуйте, Малышев.

Вы писали 10 января 2005 г., 20:10:58:

Вызывать унаследованный деструктор мы можем только после того, как удалим все
свои наработки. Вот и не будет проблем с памятью
begin
//inherited Destroy; // вырежем отсюда
bmp.Free;
for i:= 0 to l.Count-1 do
FreeMem(l.Items[i]);
l.Destroy;
inherited Destroy; // и вставим сюда
end;

В состоянии. Но только если работа ведется в .Net например, в C#

Ответить   Mon, 10 Jan 2005 20:35:36 +0600 (#294293)

 

По-моему, форточка прекрасно очищает память умирающего процесса, независмо
от того, написан ли он на C++ или C#. Причем, она очищает не только всю
занимаемую им память, но и остальные ресурсы, типа открытых файлов и прочих
системных ценностей.

Тем не менее, лучше, конечно, всю память освобождать самому. Вдруг, эта
программа будет потом использоваться как составная часть другой программы,
тогда мусор будет накапливаться в памяти и время от времени приводить к ее
переполнению. :-) Уж лучше сразу стараться быть аккуратным.

Номер выпуска : 3922
Возраст листа : 476 (дней)
Количество подписчиков : 517
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/294344
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

-*Информационный канал Subscribe.Ru
Подписан адрес:
Код этой рассылки: comp.soft.prog.prog
Написать в лист: mailto:comp.soft.prog.prog-list@subscribe.ru
Отписаться: mailto:comp.soft.prog.prog--unsub@subscribe.ru?subject=comp.soft.prog.prog

http://subscribe.ru/ http://subscribe.ru/feedback

Ответить   Tue, 11 Jan 2005 00:42:31 +0500 (#294344)

 

Здравствуйте, Юрчик.

Вы писали 11 января 2005 г., 1:42:31:

Сколько пользуюсь - ни фига подобного. А вот ежли пользоваться IDE -
тогда да. И согласно общему мелкомягковскому мнению, к коему я
присоединяюсь, нормально и эффективно убирать за собой и чужими
программами умеет только нечто, написанное с использованием .NET

Фахт :))) Сколько на этом памяти сгорело

Ответить   Tue, 11 Jan 2005 20:44:04 +0600 (#295066)

 

Привет Юрчик,

Monday, January 10, 2005, 10:42:31 PM, вы писали:

Не факт -> когда я писл лабораторные по Компьютерной графике
(требовались большие объемы памяти), а при тестировании всегда есть
ошибки (а как же без них) - то ОС приходилось перегружать после 20-21
компиляции!!! А то системных ресурсов не оставалось :(

Афоризм напоследок: Кто ходит в гости "за рулем", то поступает глупо.
14 января 2005 г. 7:46:33

Просто студент
Eugene mailto:rav***@o*****.ru

Номер выпуска : 3937
Возраст листа : 480 (дней)
Количество подписчиков : 519
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/296838
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Fri, 14 Jan 2005 07:48:58 +0300 (#296838)

 

Здоровеньки булы, Eugene the Monster!

14 января 2005 г., пятница, 09:48:58 (GMT+05:00), пришел ко мне
почтальон Почкин и всучил письмо с пометкой "Ошибка при удалении обьекта. Delphi",
в котором сообщалось следующее:

Да в винде с этим вообще глухо - не далее двух дней назад обрабатывал
исходники из статей (~2600 файлов в каждом по несколько кусков кода) с
помощью консольной версии pasind-а (обрабатывает форматирование
исходников - отступы всякие, регистр символов и т.п.) в общем где-то
после 1500 файлов винда (win2k sp4 + 160 mb оперы) зависала наглухо
успев только показать табличку - "недостаточно системных ресурсов для
выполнения операции"
Причем в программе (моей) я просто запускал (createprocess) bat файл в
котром уже были прописаны все настройки для pasind (console version).

В общем на винду надеяться нельзя - не умеет она утечки отлавливать

Ответить   Александр Томилов Mon, 17 Jan 2005 22:21:45 +0500 (#299165)

 

Так ведь из компилятора почти наверняка не выходил время от времени.
С чего же это операционка станет сама освобождать ресурсы,
которые захватил компилятор и забыл освободить...

Что-то я не помню ни одной операционки которая могла бы сама решить,
что процесс больше не будет пользоваться тем или иным ресурсом,
если он сам не закрыл все ссылки на него. Освобождаются они
лишь при завершении процесса. Так что в этом отношении
на Windows незачем грешить.
А насчет конкретного случая - есть любимая ошибка использующих
CreateProcess - даже если закрывают дескриптор процесса в структуре
PROCESS_INFORMATION, забывают закрыть дескриптор потока.
В сочетании с возможными утечками ресурсов в запускаемом
процессе это при больших нагрузках убьет кого угодно.
Возможно, у Вас произошло именно это. Кстати, запускать bat
через CreateProcess, мягко говоря, не слишком эффективно.
Почему бы не собрать командную строку в памяти
и создавать процесс с указанием exe?

Рано или поздно при некотором упорстве можно решить почти любую
проблему. Так что не будем зря обижать программистов
Microsoft, тоже ведь люди :)
Лет семь имею дело с их детищем и десятки, а то и сотни глюков, с
которыми я встречался, были вызваны ошибками использующих
Windows программистов, иногда ошибками сред разработки
и очень редко проблемами самой операционки.
Это вызывает некоторое уважение к тем, кто ее пишет :)

Не очень подробно, видимо эта проблема Вас не
очень беспокоит или Вы ее решили.

Возможно, это не имеет отношения к упомянутому случаю, но на всякий
случай скажу, что иногда возникают трудноуловимые ошибки с
исключениями плавающей арифметики при взаимодействии
программ на C и Delphi. Это бывает вызвано тем, что по умолчанию
в C все исключения плавающей арифметики запрещены, а в Delphi
исключения по переполнению, делению на ноль и недопустимой
операции разрешены. Поэтому при переходе из кода на C, не
сбросившего флаги исключений, в код на Delphi во время
проверки на наличие исключений плавающей
арифметики возникают "ошибки ниоткуда".

Номер выпуска : 3956
Возраст листа : 484 (дней)
Количество подписчиков : 519
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/299336
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Tue, 18 Jan 2005 10:07:52 +0300 (#299336)

 

Здравствуйте !


Кстати, почитайте вот:
http://russian.joelonsoftware.com/Articles/HowMicrosoftLosttheWaronA.htm
l

Оч. интересно и просто познавательно :)
Там как раз упоминается что в винде делали для защиты от ошибок
программистов при работе с памятью.

--
С уважением, Вахтуров Виктор.

Номер выпуска : 3957
Возраст листа : 492 (дней)
Количество подписчиков : 521
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/304513
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Tue, 18 Jan 2005 10:38:17 +0300 (#304513)

 

Здоровеньки булы, Victor V. Vakchturov!

18 января 2005 г., вторник, 12:38:17 (GMT+05:00), пришел ко мне
почтальон Почкин и всучил письмо с пометкой "Ошибка при удалении обьекта. Delphi",
в котором сообщалось следующее:


Не ну это пи***ц какой-то!!!!!!!!

Они сообщили это разработчикам Windows, которые дизассемблировали
SymCity, шаг за шагом в дебаггере найдя ошибку, и добавили
специальный код, проверяющий наличие SymCity в памяти и запускающий
распределитель памяти в специальном режиме, в котором SymCity
разрешается использовать память после ее освобождения.
И это было в порядке вещей.

Это умом можно еба***ься!!! Из-за каких-то дебильных
ламеров-пользователей так поганить операционку, кажеться я начинаю
понимать почему любят Linux/Unix там такой поддержки "совместимости" точно нет.

Я понимаю еще этот момент (но не принимаю):

или полагается на ошибочное поведение функции, которое было ошибочным
в Windows n, но уже исправлено в Windows n+1.

Но изменение кода операционки из-за использования программой
недокументированных функций предыдущей версии windows - нет уж увольте!

PS: Сорри за мат, не могу об этой статье без эмоций!

Ответить   Wed, 26 Jan 2005 19:08:38 +0500 (#305112)

 

Здоровеньки булы, Емельянов Алексей!

18 января 2005 г., вторник, 12:07:52 (GMT+05:00), пришел ко мне
почтальон Почкин и всучил письмо с пометкой "Ошибка при удалении обьекта. Delphi",
в котором сообщалось следующее:

function Start(FileName: string; TmpPasToProcessing: string): boolean;
var
si: TStartupInfo;
p: TProcessInformation;
tmp: DWORD;
begin
Result := true;
FillChar(Si, SizeOf(Si), 0);
with Si do
begin
cb := SizeOf( Si);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := SW_HIDE;
end;
if not Createprocess('d:\p\1.bat', '', nil, nil, true, CREATE_NEW_CONSOLE,
nil, 'D:\p', si, p)
then
begin
ShowMessage(SysErrorMessage(GetLastError));
FormatForm.Terminate := true;
end;
tmp := GetTickCount;
while Waitforsingleobject(p.hProcess, 10) = WAIT_TIMEOUT do
begin
if GetTickCount - Tmp > 500 then
begin
Result := false;
Click;
TerminatePasind;
FormatForm.MemoNotProcessing.Lines.Add(IntToStr(GetTickCount) +':limit
' + FileName);
FormatForm.MemoNotProcessing.Lines.Add(TmpPasToProcessing);
FormatForm.MemoNotProcessing.Lines.SaveToFile('d:\MemoNotProcessing.txt');
TerminateProcess(p.hProcess, 0);
end;
Application.ProcessMessages;
end;
CloseHandle(p.hProcess);
CloseHandle(p.hThread);
end;

Причем условие GetTickCount - Tmp > 500 не выполнялось, однако -
утечка налицо.

Ну чуть поподробнее:
По MouseWheelDown производилась такая штука:
Scale := Scale - Scale / 10;
glScalef (Scale, Scale, Scale);

Короче изменение масштаба, дык вот это изменение происходило без
ошибок в win2k и выдавала division by zero в XP при переходе через
Scale = 0

Ну в общем правда :) Я эту прогу просто так сваял чтобы показать
другу что с OpenGL работать умею.

Кстати да: может это просто это opengl32.dll в XP глючная (для
glScalef). Но это вряд ли.

Ответить   Александр Томилов Tue, 18 Jan 2005 14:10:22 +0500 (#304517)