![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Найдите, пожалуйста, ошибку в алгоритме особождения ресурсов [D6, Win2k]
Сатир © (2002-11-06 19:24:00)есть такой конструктор и деструктор
constructor TColorMap.Create(AOwner: TComponent);
begin
inherited;
fColors := TSClrCollection.Create(Self);
fChilds := TList.Create;
end;
destructor TColorMap.Destroy;
begin
fUpdating := True;
ClearChilds;
fColors.Free;
fChilds.Free;
Base := nil;
inherited;
end;
деструктор вызывает ClearChilds, которая определена следующим образом:
procedure TColorMap.ClearChilds;
var C: TObject;
begin
while fChilds.Count>0 do
begin
C := TObject(fChilds.Last);
if C is TColorMap then TColorMap(C).Base := nil
else if C is TStyleColors then
TStyleColors(C).Map := nil;
end;
end;
При удалении объекта из форму путём нажатия клавиши Del присходит какая-то дикая ошибка в rtl60.bpl, которая влечет за собой кучу других страшных ошибок, вплоть до того, что невозможно даже сохранить текущий проект и вийди из IDE без Access violation.
Но когда я ремарю в деструкторе ClearChilds, всё работает нормально. Возникает подозрение, а не происходит ли где утечка памяти из-за не вызова последней?
ЗЫ. исходный код не мой
Сатир (2002-11-10 22:18:00) [1]2Alex44 (10.11.02 21:46)
как какая? берёшь тестовую прогу, удаляешь с неё компонент в design-time"e, и всё. Куча багов, да причём таких, что без ошибки невозможно даже закрыть делфи нормально, не говоря уже о элементарной возможности сохранения и закрытия всего проекта...
Alex44 (2002-11-10 21:46:00) [2]Esli v run-time vse OK, to kakaya zhe eto oshibka? :)
Сатир (2002-11-10 20:12:00) [3]короче, цикл
procedure TColorMap.ClearChilds;
var C: TObject;
begin
while fChilds.Count>0 do
begin
C := TObject(fChilds.Last);
if C is TColorMap then TColorMap(C).Base := nil
else if C is TStyleColors then
TStyleColors(C).Map := nil;
end;
end;
всё таки заканчивается, пробовал создавать и удалять в run-time
хотя, возникает вопрос: а не может случайно быть такого, чтоб ошибку design-time нельзя было бы выявить путём тестирования в режиме run-time?
Alex44 (2002-11-09 19:39:00) [4]Po vidimomu, za eto otvechaet TColorMap.SetBase i TStyleColors.SetMap (sm. moj code naverhu): pri vystavlenii Base v nil oni ubirayut ssylku na sebya is Base.fChildren, i tem samym fCildren.Count umen"shaetsya i fChildren.Last stanovitsya predydushim elementom. Eto prosto neobhodimo, esli ne isklyucheny krugovye ssylki.
Shc (2002-11-09 15:51:00) [5]Извините, ребят, за попутный вопрос, но где в коде
while fChilds.Count>0 do
begin
C := TObject(fChilds.Last);
if C is TColorMap then TColorMap(C).Base := nil
else if C is TStyleColors then
TStyleColors(C).Map := nil;
end;
переход на следующий элемент (не пойму, почему нет зацикливания)?
Набережных С. (2002-11-07 20:43:00) [6]Уже лучше, чем ничего:) Постарайся сузить "круг подозреваемых".
И посмотри, нет ли где такого :
if csDesigning in ComponentState ...
Возможно, разгадка в этом.
Сатир (2002-11-07 19:41:00) [7]2Набережных С. (07.11.02 18:49)
идея замечательная, но пока от неё толку мало, потому что при создании и удалении в run-time ничего страшного не происходит. насколько удалось выяснить, эта проблема касается взаимодействия с другими компонентами из этого же пакета, но с какими, пока неизвестно;(
Набережных С. (2002-11-07 18:49:00) [8]>Сатир © (07.11.02 17:14)
Просто замечательная, жаль, что не моя:))))
Сатир (2002-11-07 17:14:00) [9]2Набережных С. (07.11.02 16:57)
неплохая идея;)
Набережных С. (2002-11-07 16:57:00) [10]>Сатир ©
А ты пробовал создавать объект в run-time и пройтись отладчиком по деструктору?
Сатир (2002-11-07 13:49:00) [11]2 Набережных С. (06.11.02 21:14) и Юрий Зотов © (07.11.02 00:42)
понятное дело, но ведь исходники не мои, и архитектуру взаимодейстия создавал не я. мне нужно всего лишь добавить два редактора свойств и попутно найти ошибки в этом пакете. А с выключенным компом без доступа к исходникам я это вряд ли сделаю. Ваш подход нужно применять на начальной стадии проектирования, когда ещё ничего нет, это да, самое главное - спланировать на бумажке, что ты хочешь на(ш)кодить, а потом, согласно нарисованной инструкции приниматься за работу. Но в данном случае, имхо, другая ситуация.
Но в любом случае, прийдётся выяснить, кто чей папа/мама/ребёнок и кто/что/кому говорит.
Ладно вернёмся к нашим баранам.
2Андрей Прокофьев © (06.11.02 20:11)
>UpdateColors(0);
>CompileColors;
>там fBase не участвует?
привожу исходный код
procedure TColorMap.UpdateColors(Index: Integer);
var I,CC: Integer;
begin
if fUpdating then Exit;
fColors.BeginUpdate;
if Index=0 then CC := 0
else CC := 1;
try
for I:= Index to fColors.Count-1 do
Inc(CC,CalculateColor(TStyleColor(fColors.Items[I])));
fUpdating := True;
finally
fColors.EndUpdate;
fUpdating := False;
end;
// if CC>0 then
with fChilds do
for I:=0 to Count-1 do
if TObject(Items[I]) is TColorMap then
TColorMap(Items[I]).UpdateColors(0)
else if TObject(Items[I]) is TStyleColors then
TStyleColors(Items[I]).CompileColors;
end;
procedure TStyleColors.CompileColors;
var I: Integer;
L: TStringList;
begin
L := TStringList.Create;
try
L.CommaText := fFormulas;
SetLength(fColors,L.Count);
for I:=0 to L.Count-1 do
fColors[I] := MakeColor(L[I]);
finally
L.Free;
end;
if Assigned(fOnChange) then OnChange(Self);
end;
Юрий Зотов (2002-11-07 00:42:00) [12]> Сатир
НА 100% присоединяюсь к "Набережных С. (06.11.02 21:14)".
Прислушайтесь, не пожалеете.
Набережных С. (2002-11-06 21:14:00) [13]>Сатир ©
Выключи компьютер. Возьми лист бумаги и нарисуй. Нарисуй схему взаимодействия твоих компонентов. Что как, когда и на кого должно воздействовать и как тот должен реагировать. Попутно отметь, где какие ресурсы захватываются, и когда их нужно и можно освободить. Учти реакцию на сообщения. Пока не будет полной ясности - от запуска проги до завершения - не включай ящик. Если получится, то у тебя никогда больше не будет возникать подобных вопросов. Потом сможешь проделывать это в уме, но первый раз - ОБЯЗАТЕЛЬНО на бумаге!
Alex4444444444 (2002-11-06 20:45:00) [14]T.k. my dogovorilis", chto Last---eto TColorMap i iz Destroy on vyzovet Extract, to Count budet umen"shat"sya. Voobshe, konechno, krugovye ssylki---poganaya vesh"...
Андрей Прокофьев (2002-11-06 20:37:00) [15]2 Alex4444444444 (06.11.02 20:28)
1 Call Extract to remove an item from the list. After the item is removed, all the objects that follow it are moved up in index position and Count is decremented.
with fChildren do
while Count > 0 do TObject(Last).Free;
TObject(Last).Free - не удаляет элемент из списка - цикл бесконечный
Alex4444444444 (2002-11-06 20:28:00) [16]Eshe odno zamechanie: esli Vy sdelaete fBase...Extract, to potom mozhno (i dazhe NUZHNO) ispol"zovat" Vash podhod:
with fChildren do
while Count > 0 do TObject(Last).Free;
Alex4444444444 (2002-11-06 20:24:00) [17]Pardon, dazhe, skoree, naoborot:
destructor TColorMap.Destroy;
begin
if Assigned(fBase) then
fBase.fChildren.Extract(Self);
...
ClearChildren;
...
inherited;
end;
t.k., esli fBase sredi fChildren, to ona nachnet osvobozhdat"sya i vyzivet Destroy snova ==> beskonechnyj cycle ili access violation.
Alex4444444444 (2002-11-06 20:20:00) [18]Vy dolzhny tochno ponyat", kto kem vladeet. (Naprimer, pozabotit"sya, chto NE proishodit ColorMap1.Base := ColorMap2 i ColorMap2.Base := ColorMap1, t.k. v etom sluchae Vy budete pytat"sya udalit" uzhe udalennuyu TColorMap.) Esli eto vse zhe neobhodimo, oni dolzhny drug druga opoveshat" ob udalenii.
E.g.,
destructor TColorMap.Destroy;
begin
ClearChildren;
...
if Assigned(fBase) then
fBase.fChildren.Extract(Self);...
inherited;
end;
Сатир (2002-11-06 20:18:00) [19]ладно, всем спасибо, а в особенности, Андрею Прокофьеву, бегу.
надеюсь, продолжим завтра...
Сатир (2002-11-06 20:15:00) [20]2Андрей Прокофьев © (06.11.02 20:00)
неподходит
плюётся таким макаром:
Access violation at address 40005988 in module "rtl60.bpl".
Read of address 0B1A6B18.