Форум: "Начинающим";
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];
ВнизОшибка при удалении контролов Найти похожие ветки
← →
Германн © (2011-06-23 02:52) [0]Вот впервые в моей практике "стабильно" получаю 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://delphimaster.net/view/2-1308354496/
← →
KilkennyCat © (2011-06-23 03:42) [1]а:=sPanel1.ControlCount-1;
for i:=а downto 0 do sPanel1.Controls[i].Free;
← →
Германн © (2011-06-23 04:09) [2]
> KilkennyCat © (23.06.11 03:42) [1]
>
> а:=sPanel1.ControlCount-1;
> for i:=а downto 0 do sPanel1.Controls[i].Free;
Хм. Именно такой код я и привел в вопросе.
Наскоко я вообще знаю и понимаю Дельфи.
← →
KilkennyCat © (2011-06-23 05:18) [3]есть некоторая разница.
во-первых, нет постоянного вычисления sPanel1.ControlCount-1.
во-вторых (но тут я могу ошибаться) ав может возникать из-за того, что sPanel1.ControlCount-1 при очередном вычислении может вернуть индекс объекта, находящегося в процессе удаления, а потом ему еще раз фрии...
← →
Ega23 © (2011-06-23 08:18) [4]
> KilkennyCat © (23.06.11 05:18) [3]
Костя, не позорься.
> Строка кода где случается сей AV такова:
> for i:=sPanel1.ControlCount-1 downto 0 do sPanel1.Controls[i].
> Free;
Controls - это то, для чего Parent. Components - для чего Owner.
Создавай контролы с Owner = Panel, очищай -
for i:= panel.ComponentCount - 1 downto 0 do
НУ и эта... Ошибка может быть совсем не в этом. :) Что CallStack говорит?
← →
BoB (2011-06-23 09:14) [5]Хм..
А у меня и [0] и [1] без проблем.
Контролы : три батона и три лабеля, созданы в дезайнтаме (D7)
Так что (ИМХО)
[4] "Ошибка может быть совсем не в этом."
← →
Anatoly Podgoretsky © (2011-06-23 09:34) [6]Похоже, что sPanel1 равно nil
Восспользуйся отладчиком и посмотри значение.
← →
RWolf © (2011-06-23 09:52) [7]думается мне, что проблема в смешении сущностей Components[] (те компоненты, за чьё удаление отвечает контейнер при собственном удалении) и Controls[] (контролы, которые он должен показывать внутри собственного окна).
а именно, в том, что в приведённом примере что-то из содержимого удаляется автоматом по два раза.
← →
KilkennyCat © (2011-06-23 10:08) [8]
> Ega23 © (23.06.11 08:18) [4]
а в чем именно я ошибся?
← →
Ega23 © (2011-06-23 10:33) [9]
> а в чем именно я ошибся?
в "во-первых".
← →
Alex_C (2011-06-23 10:42) [10]Ошибка есть :)
Ошибка в том, какие элементы таким способом удадяешь.
Предлагаю все сделать следующий эксперимент и удивиться:
делаете проект с формой и панелью. На нее поочередности наносите элементы и удаляете их. Все будет нормально до тех пор, пока на форме не появится TLabeledEdit - при попытке его удалить возникнет AV.
← →
sniknik © (2011-06-23 10:44) [11]> а в чем именно я ошибся?
значения для for вычисляются 1 раз.
а работает?
with sPanel1 do while ControlCount > 0 do Controls[0].Free;
> Ошибка может быть совсем не в этом
а, например в том, что в деструкторе 100 контрола есть Free/дестрой для 17-го...
← →
Ega23 © (2011-06-23 10:54) [12]
> делаете проект с формой и панелью. На нее поочередности
> наносите элементы и удаляете их. Все будет нормально до
> тех пор, пока на форме не появится TLabeledEdit - при попытке
> его удалить возникнет AV.unit Unit18;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm18 = class(TForm)
Panel1: TPanel;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form18: TForm18;
implementation
{$R *.dfm}
procedure TForm18.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := Panel1.ComponentCount - 1 downto 0 do
Panel1.Components[i].Free;
end;
procedure TForm18.FormCreate(Sender: TObject);
begin
with TLabeledEdit.Create(Panel1) do
begin
SetBounds(10, 10, 100, 100);
Parent := Panel1;
end;
end;
end.
Никаких AV. ЧЯДНТ?
← →
Alex_C (2011-06-23 10:56) [13]А у меня стабильная ошибка. Перед тем как написать специально несколько раз проверил....
Delphi 7
← →
Ega23 © (2011-06-23 10:57) [14]
> А у меня стабильная ошибка. Перед тем как написать специально
> несколько раз проверил....
Код в студию.
← →
Alex_C (2011-06-23 10:58) [15]Причем как я уже написал - только на TLabeledEdit (это ж как бы 2 контрола - может в этом проблема?) Сдается мне что может быть это конкретно проблема 7 Дельфи.
← →
Alex_C (2011-06-23 11:00) [16]
> Код в студию.
А никакого кода нет :)
Я ж написал - просто на панель в Дельфи набросал кучу разных кампонент. И удалял их по нажатию на кнопку. Все компоненты, кроме TLabeledEdit удалялись без проблем. В реал-тайме я их не создавал.
← →
Ega23 © (2011-06-23 11:04) [17]
> (это ж как бы 2 контрола - может в этом проблема?
Не должно быть никакой проблемы.
← →
Ega23 © (2011-06-23 11:05) [18]Попробую спецом дома D7 поставить и проверить. Но это только вечером.
← →
sniknik © (2011-06-23 11:13) [19]> А у меня стабильная ошибка. Перед тем как написать специально несколько раз проверил....
> Delphi 7
sniknik © (23.06.11 10:44) [11]
← →
Rouse_ © (2011-06-23 11:32) [20]
> KilkennyCat © (23.06.11 05:18) [3]
> есть некоторая разница.
> во-первых, нет постоянного вычисления sPanel1.ControlCount-1
Костик, ты чего, перегрелся? :)
Это-ж не WHILE и не REPEAT цикл, а FOR, в котором начальное и конечное значение итератора рассчитываются только один раз :)
← →
KilkennyCat © (2011-06-23 11:39) [21]нда... забыл просто. каша в голове уже от работы сразу в куче всякого... значит, завтра поеду в деревню, самогон, свежий воздух, сон и никаких компьютеров.
← →
Rouse_ © (2011-06-23 11:44) [22]ЗЫ: а вообще дело в том что TLabeledEdit состоит из двух контролов, поэтому при вызове Free разрушаются оба и соответственно позиция итератора не соответствует оставшемуся количеству контролов.
Посему правильный вариант:while Panel1.ControlCount <> 0 do
Panel1.Controls[0].Free;
← →
sniknik © (2011-06-23 11:47) [23]> Посему правильный вариант:
- доктор меня все игнорируют.
- следующий!
← →
Alex_C (2011-06-23 11:48) [24]
> TLabeledEdit состоит из двух контролов
Собственно о чем я и писал.
> Посему правильный вариант:
+1!
← →
Rouse_ © (2011-06-23 12:07) [25]точнее еще более правильный вот так:
while Panel1.ControlCount <> 0 do
Panel1.Controls[Panel1.ControlCount - 1].Free;
дабы List не ресортился при каждом удалении нулевого элемента, а просто отсекался с хвоста ;)
← →
Ega23 © (2011-06-23 12:08) [26]
> Посему правильный вариант:
> while Panel1.ControlCount <> 0 do
> Panel1.Controls[0].Free;
Это в том случае, если ты хочешь удалить и те контролы, что были созданы в дизайн-тайм, и те, что в ран-тайм.
А вот если ты их все создаёшь в ран-тайм сOwner=Panel1
, а потом грохаешь либо Panel1 целиком, либо проходишь поPanel1.ComponentCount-1 downto 0
, то никакого AV не будет.
← →
Ega23 © (2011-06-23 12:09) [27]
> точнее еще более правильный вот так:
Тоже вариант.
← →
Омлет © (2011-06-23 12:14) [28]> Ega23 © (23.06.11 12:08) [26]
> А вот если ты их все создаёшь в ран-тайм
Тогда лучше ссылки на них хранить в отдельном массиве и не иметь никаких проблем.
← →
Ega23 © (2011-06-23 12:29) [29]
> Тогда лучше ссылки на них хранить в отдельном массиве и
> не иметь никаких проблем.
А зачем лишнюю сущность заводить, если ужеTComponent.FComponents: TList
есть?
Впрочем, это философский вопрос.
← →
sniknik © (2011-06-23 12:37) [30]> дабы List не ресортился при каждом удалении нулевого элемента, а просто отсекался с хвоста ;)
пофиг. в вызове RemoveControl все одно есть ресорт, с какого конца не удаляй. а без него, ибез ресорта (код из TWinControl.Destroy;)
I := ControlCount;
while I <> 0 do
begin
Instance := Controls[I - 1];
Remove(Instance);
Instance.Destroy;
I := ControlCount;
end;
, должен быть доступ к приватному методу.
← →
Омлет © (2011-06-23 12:48) [31]> А зачем лишнюю сущность заводить, если уже TComponent.FComponents: TList есть?
Только вот к Panel1.Controls он отношения не имеет )
← →
Юрий Зотов © (2011-06-23 13:54) [32]> Ega23 © (23.06.11 12:29) [29]
> А зачем лишнюю сущность заводить, если уже
> TComponent.FComponents: TList есть?
Насколько помню, у него к этой панели еще и меню привязано, через Owner. Правда, непонятно зачем - но это уже другой вопрос.
← →
Ega23 © (2011-06-23 14:02) [33]
> Насколько помню, у него к этой панели еще и меню привязано,
> через Owner. Правда, непонятно зачем - но это уже другой
> вопрос.
Не, ну тогда вообще отдельный компонент имеет смысл делать. ИМХО. Тогда уже точно никаких непоняток не будет - накидал что надо, ссылки сохранил как Омлет в [28] предложил. И делай что хочешь.
← →
Германн © (2011-06-24 01:59) [34]Вчера три раза подряд получил сие AV выполняя одни и те же действия.
Сегодня как не стараюсь, не получаю AV.
Ну я понимаю, что AV это такая "гадость", которая может проявляться (и это плюс), а может и не проявляться.
У меня только один "вопрос неуча". А то что я удаляю Контролы методомControls[i].Free
может как-то влиять?
Т.е. не нужно ли мне вызывать метод Free реального контрола?
← →
Омлет © (2011-06-24 08:22) [35]> Т.е. не нужно ли мне вызывать метод Free реального контрола?
Ты его и вызываешь.
← →
Ega23 © (2011-06-24 10:08) [36]
> А то что я удаляю Контролы методом
> Controls[i].Free может как-то влиять?
Ты чё, ветку не прочитал? По-моему, уже все возможные варианты перебрали, не?
← →
Anatoly Podgoretsky © (2011-06-24 10:54) [37]> Германн (24.06.2011 01:59:34) [34]
Ты и так вызываешь методы реального объекта
к просто сказал сделать,
сделано.
← →
Германн © (2011-06-25 02:02) [38]
> Омлет © (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) [39]
> Омлет © (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]
>
> Ты и так вызываешь методы реального объекта
> к просто сказал сделать,
> сделано.
>
Наверно у меня вчера была "нелетная погода". И в результате я грешил на "непогрешимые основы".
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2011.10.16;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.004 c