![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка при удалении контролов
Германн © (2011-06-23 02:52:00)Вот впервые в моей практике "стабильно" получаю AV в "стабильной" строке кода "стабильно в некотором моменте рантайма" и не могу понять причину.
Строка кода где случается сей AV такова:
for i:=sPanel1.ControlCount-1 downto 0 do sPanel1.Controls[i].Free;
Сообщение об ошибке такое: Access violation at address 005E6EA3 in module 'ХХХ.exe'. Read of address 00000024
Суть кода - удалить все имеющиеся контролы на панели, чтобы пользователь мог создать другие.
Продолжение задачи http://www.delphimaster.ru/cgi-bin/forum.pl?id=1308354496&n=18
Германн (2011-06-25 02:02:00) [1]
> Омлет © (24.06.11 08:22) [35]
>
> > Т.е. не нужно ли мне вызывать метод Free реального контрола?
>
>
> Ты его и вызываешь.
>
> Ega23 © (24.06.11 10:08) [36]
>
>
> > А то что я удаляю Контролы методом
> > Controls[i].Free может как-то влиять?
>
>
> Ты чё, ветку не прочитал? По-моему, уже все возможные варианты
> перебрали, не?
>
> Anatoly Podgoretsky © (24.06.11 10:54) [37]
>
> > Германн (24.06.2011 01:59:34) [34]
>
> Ты и так вызываешь методы реального объекта
> к просто сказал сделать,
> сделано.
>
Наверно у меня вчера была "нелетная погода". И в результате я грешил на "непогрешимые основы".
Германн (2011-06-25 02:02:00) [2]
> Омлет © (24.06.11 08:22) [35]
>
> > Т.е. не нужно ли мне вызывать метод Free реального контрола?
>
>
> Ты его и вызываешь.
>
> Ega23 © (24.06.11 10:08) [36]
>
>
> > А то что я удаляю Контролы методом
> > Controls[i].Free может как-то влиять?
>
>
> Ты чё, ветку не прочитал? По-моему, уже все возможные варианты
> перебрали, не?
>
> Anatoly Podgoretsky © (24.06.11 10:54) [37]
>
> > Германн (24.06.2011 01:59:34) [34]
>
> Ты и так вызываешь методы реального объекта
> к просто сказал сделать,
> сделано.
>
Наверно у меня вчера была "нелетная погода". И в результате я грешил на "непогрешимые основы".
Anatoly Podgoretsky (2011-06-24 10:54:00) [3]> Германн (24.06.2011 01:59:34) [34]
Ты и так вызываешь методы реального объекта
к просто сказал сделать,
сделано.
Ega23 (2011-06-24 10:08:00) [4]
> А то что я удаляю Контролы методом
> Controls[i].Free может как-то влиять?
Ты чё, ветку не прочитал? По-моему, уже все возможные варианты перебрали, не?
Омлет (2011-06-24 08:22:00) [5]> Т.е. не нужно ли мне вызывать метод Free реального контрола?
Ты его и вызываешь.
Германн (2011-06-24 01:59:00) [6]Вчера три раза подряд получил сие AV выполняя одни и те же действия.
Сегодня как не стараюсь, не получаю AV.
Ну я понимаю, что AV это такая "гадость", которая может проявляться (и это плюс), а может и не проявляться.
У меня только один "вопрос неуча". А то что я удаляю Контролы методом
Controls[i].Freeможет как-то влиять?
Т.е. не нужно ли мне вызывать метод Free реального контрола?
Ega23 (2011-06-23 14:02:00) [7]
> Насколько помню, у него к этой панели еще и меню привязано,
> через Owner. Правда, непонятно зачем - но это уже другой
> вопрос.
Не, ну тогда вообще отдельный компонент имеет смысл делать. ИМХО. Тогда уже точно никаких непоняток не будет - накидал что надо, ссылки сохранил как Омлет в [28] предложил. И делай что хочешь.
Юрий Зотов (2011-06-23 13:54:00) [8]> Ega23 © (23.06.11 12:29) [29]
> А зачем лишнюю сущность заводить, если уже
> TComponent.FComponents: TList есть?
Насколько помню, у него к этой панели еще и меню привязано, через Owner. Правда, непонятно зачем - но это уже другой вопрос.
Омлет (2011-06-23 12:48:00) [9]> А зачем лишнюю сущность заводить, если уже TComponent.FComponents: TList есть?
Только вот к Panel1.Controls он отношения не имеет )
sniknik (2011-06-23 12:37:00) [10]> дабы List не ресортился при каждом удалении нулевого элемента, а просто отсекался с хвоста ;)
пофиг. в вызове RemoveControl все одно есть ресорт, с какого конца не удаляй. а без него, ибез ресорта (код из TWinControl.Destroy;)
I := ControlCount;
while I <> 0 do
begin
Instance := Controls[I - 1];
Remove(Instance);
Instance.Destroy;
I := ControlCount;
end;
, должен быть доступ к приватному методу.
Ega23 (2011-06-23 12:29:00) [11]
> Тогда лучше ссылки на них хранить в отдельном массиве и
> не иметь никаких проблем.
А зачем лишнюю сущность заводить, если ужеTComponent.FComponents: TListесть?
Впрочем, это философский вопрос.
Омлет (2011-06-23 12:14:00) [12]> Ega23 © (23.06.11 12:08) [26]
> А вот если ты их все создаёшь в ран-тайм
Тогда лучше ссылки на них хранить в отдельном массиве и не иметь никаких проблем.
Ega23 (2011-06-23 12:09:00) [13]
> точнее еще более правильный вот так:
Тоже вариант.
Ega23 (2011-06-23 12:08:00) [14]
> Посему правильный вариант:
> while Panel1.ControlCount <> 0 do
> Panel1.Controls[0].Free;
Это в том случае, если ты хочешь удалить и те контролы, что были созданы в дизайн-тайм, и те, что в ран-тайм.
А вот если ты их все создаёшь в ран-тайм сOwner=Panel1, а потом грохаешь либо Panel1 целиком, либо проходишь поPanel1. ComponentCount-1 downto 0, то никакого AV не будет.
Rouse_ (2011-06-23 12:07:00) [15]точнее еще более правильный вот так:
while Panel1.ControlCount <> 0 do
Panel1.Controls[Panel1.ControlCount - 1].Free;
дабы List не ресортился при каждом удалении нулевого элемента, а просто отсекался с хвоста ;)
Alex_C (2011-06-23 11:48:00) [16]
> TLabeledEdit состоит из двух контролов
Собственно о чем я и писал.
> Посему правильный вариант:
+1!
sniknik (2011-06-23 11:47:00) [17]> Посему правильный вариант:
- доктор меня все игнорируют.
- следующий!
Rouse_ (2011-06-23 11:44:00) [18]ЗЫ: а вообще дело в том что TLabeledEdit состоит из двух контролов, поэтому при вызове Free разрушаются оба и соответственно позиция итератора не соответствует оставшемуся количеству контролов.
Посему правильный вариант:
while Panel1.ControlCount <> 0 do
Panel1.Controls[0].Free;
KilkennyCat (2011-06-23 11:39:00) [19]нда... забыл просто. каша в голове уже от работы сразу в куче всякого... значит, завтра поеду в деревню, самогон, свежий воздух, сон и никаких компьютеров.
Rouse_ (2011-06-23 11:32:00) [20]
> KilkennyCat © (23.06.11 05:18) [3]
> есть некоторая разница.
> во-первых, нет постоянного вычисления sPanel1.ControlCount-1
Костик, ты чего, перегрелся? :)
Это-ж не WHILE и не REPEAT цикл, а FOR, в котором начальное и конечное значение итератора рассчитываются только один раз :)