Форум: "Основная";
Текущий архив: 2004.02.10;
Скачать: [xml.tar.bz2];
ВнизПочему падает TForm.Create? Найти похожие ветки
← →
alexEagle (2004-01-29 00:42) [0]Я не могу понять почему два идентичных вызова одного и того же метода приводят к AccessViolation в одном случае и нормальной работе в другом.
Код такой:
procedure TfrmMain.ShowDispensers(bShow: Boolean=true);
...
frmTable := TfrmTable.Create(Self);
...
Причем программа падает, если вызов этой функции происходит из обработчика меню, и работает (по крайней мере окно создается), если вызвается в обработчике сообщения WM_USER в том же окне.
Трассировка не помогла, потому как ушел в дебри и потом застрял на нотификациях.
Люди добрые, поможите кто чем может :)
← →
Германн (2004-01-29 01:12) [1]Кода слишком мало для анализа причин ошибки.
← →
sniknik (2004-01-29 08:23) [2]в TfrmTable в onCreate чтонибудь делается? на самой форме чтонибудь лежит?
убери все и добавляй по одному действию/элементу, как начнет вылетать так найдеш причину.
но похоже(AccessViolation) у тебя там обрашение к чемуто что несоздано/уже освобождено.
← →
Digitman (2004-01-29 08:44) [3]
> alexEagle © (29.01.04 00:42)
> приводят к AccessViolation
"Search | Find Error ..." что говорит ? на какую строчку указывает ?
← →
Broot (2004-01-29 08:54) [4]Self на что указывает при вызове из разных процедур? Попробуй на Application заменить
← →
alexEagle (2004-01-29 11:32) [5]OnCreate отсуствует, self при создании один и тот же, в FormCreate даже не доходит - валится где-то в цепочке конструкторов (последний до которого мне позволила дойти трассировка - TControl.Create)
← →
Плохиш (2004-01-29 11:37) [6]alexEagle © (29.01.04 11:32) [5]
Не используй в коде для TfrmTable переменньх, которые автоматически создаются в модулях с формами, на пр. frmTable.
← →
alexEagle (2004-01-29 11:38) [7]Кроме того ошибка происходит по адресу 00000000 при попытке чтения из 00000000, так что Search|Find Error отдыхает
← →
sniknik (2004-01-29 11:48) [8]ну если кода OnCreate нет, то это от того что на форме лежит.
один из вариантов при котором точно такой глюк будет...
например
ShowDispensers вызывается в OnCreate главной формы (первая обычно в списке создаваемых)
на форме TfrmTable (название) лежит грид в вместо таблицы, грид или любой другой db контрол, а этот грид подключен к таблице которая в датамодуле который не первый в списке создаваемых (обычно).
если у тебя так(или похоже) то проследи, чтобы вызовы с обрашением к обьектам были после создания а не до. (и не только твоем в коде, компоненты тоже учитывай)
← →
alexEagle (2004-01-29 11:51) [9]чисто для плохиша -
if FViewType = dvtTable then frmTable := TfrmTable.Create(Self);
не работает так же как и
if FViewType = dvtTable then TfrmTable.Create(Self);
← →
Anatoly Podgoretsky (2004-01-29 11:57) [10]alexEagle © (29.01.04 11:38) [7]
Очень конкретный адрес, где то используется неинициализированый объект.
← →
Digitman (2004-01-29 11:58) [11]
> alexEagle
если на этой строчке
frmTable := TfrmTable.Create(Self);
поставить брейкпойнт, а затем выполнить шаг (F8), то как раз здесь и проиходят "чудеса" ? я правильно понял ?
← →
alexEagle (2004-01-29 12:10) [12]Да!
frmTable := TfrmTable.Create(Self);
или
TfrmTable.Create(Self);
Но объект так и не создается, в FormCreate не доходит, но уже падает
← →
Юрий Зотов (2004-01-29 12:19) [13]1. В опциях проекта включите Use debug DCUs и сделайте Build.
2. Пройдите отладчиком свой констуктор и все унаследованные до TCustomForm включительно. Либо Вы найдете причину сбоя (что скорее всего), либо он будет на строке InitInheritedComponent. Последнее означает ошибку при заливке ресурсов (маловероятную).
3. Предположительно, в конструкторе Вы обращаетесь к какому-то лежащему на форме компоненту ДО вызова inherited Create.
← →
alexEagle (2004-01-29 12:20) [14]Я скажу большее, я создал чистую форму и все равно валится
← →
Silver Alex (2004-01-29 12:25) [15]
> alexEagle © (29.01.04 12:20) [14]
код бы глянуть.Если хочешь вышли, посмотрим
← →
alexEagle (2004-01-29 12:48) [16]Вобщем трассировка приводит к методу TComponent.Notification
Понять что происходит далее я не в силах, но падает в нем при вызове из метода TComponent.InsertComponent.
← →
alexEagle (2004-01-29 12:49) [17]К сожалению код не могу выслать по нескольким причинам:
- сложность настройки IDE под проект
- это комерческий продукт, я не имею права на его сырцы
← →
Digitman (2004-01-29 12:50) [18]
> создал чистую форму и все равно валится
для "чистой" формы убери всякие self"ы и иже с ними в кач-ве владельца, поставь nil и смотри что получится
← →
Anatoly Podgoretsky (2004-01-29 12:53) [19]Если для чистой формы, то проблема в библиотеках
← →
alexEagle (2004-01-29 13:20) [20]С NIL получается то же самое. Какие библиотеки?
← →
Digitman (2004-01-29 13:25) [21]
> Какие библиотеки?
убери все лишнее из RTP либо пересобери проект без RTP
пробуй
← →
Юрий Зотов (2004-01-29 13:33) [22]> alexEagle © (29.01.04 12:48) [16]
При создании формы у Вас где-то происходит обращение к компоненту, который еще не создан (вероятнее всего, еще не залит из DFM).
> трассировка приводит к методу TComponent.Notification
Там в параметрах есть AComponent. Посмотрите в окне Watches, чему равны его Name и ClassName (включив разрешение вызова функций). И проверьте текст Notification, если он замещался.
> падает в нем при вызове из метода TComponent.InsertComponent.
Посмотрите по стеку вызовов, откуда вызывается InsertComponent и еще выше. Нужна эта информация.
← →
Digitman (2004-01-29 13:43) [23]
> трассировка приводит к методу TComponent.Notification
о какой нотификации может идти речь, если форма "чистая" и имеет nil в кач-ве владельца ? непонятно ...
← →
Юрий Зотов (2004-01-29 13:47) [24]> Digitman © (29.01.04 13:43) [23]
Значит, или не чистая, или Owner <> nil. Нам дают неточную информацию (вероятнее всего, из-за взаимного недопонимания).
← →
alexEagle (2004-01-29 13:48) [25]Речь идет о внутренней нотификиции делфи - типа вставка элемента и т.д.
← →
Digitman (2004-01-29 13:54) [26]
> внутренней нотификиции делфи
а это здесь причем ? мы же о ран-тайме здесь говорим вроде бы ?
> типа вставка элемента и т.д
какое отношение это имеет к рассматриваемой "чистой" форме с owner=nil ? никакого !
← →
sniknik (2004-01-29 13:57) [27]сомнения берут насчет того что форма чистая.
> Код такой:
> procedure TfrmMain.ShowDispensers(bShow: Boolean=true);
> ...
> frmTable := TfrmTable.Create(Self);
> ...
вместо него сделай такой код
procedure TfrmMain.ShowDispensers(bShow: Boolean=true);
begin
TForm.Create(nil).ShowModal;
end;
только именно такой! без отсебятины, и посмотри валится ли истинно "чистая" форма.
← →
Digitman (2004-01-29 13:58) [28]к тому же , если уж при ран-тайм-трассировке код странным образом приводит к вызову методов Notification() и InsertComponent(), то в Evaluate/Modify всегда можно посмотреть, кто куда вставляется и/или извещается о чем-то ... на то есть 1-й параметр AComponent этих методов ..
← →
alexEagle (2004-01-29 14:03) [29]TForm.Create(nil).ShowModal;
выдает ту же ошибку
← →
Digitman (2004-01-29 14:11) [30]т.е., если в обработчике события TMenuItem (созданного, я полагаю, в дизайн-тайм) процедуре OnClick() сразу же (безо всяких там ShowDispensers) вызвать конструктор абсолютно "чистой" формы с owner=nil, то как раз эта ситуация и происходит ? если так - чудеса да и только)..
← →
sniknik (2004-01-29 15:21) [31]alexEagle © (29.01.04 14:03) [29]
где идет вызов ShowDispensers?
десяток строк до, десяток после думаю не повредят секретности вашего проэкта.
← →
sniknik (2004-01-29 15:26) [32]просто мне уже начинает казатся что меню в одной форме а процедура описана в другой.
хотя непонятно, так должно работать если форма существует.
действитильно чудеса.
← →
Ihor Osov'yak (2004-01-29 16:10) [33]Да нет, чудес не бывает. Например, очень "умелое" юзание GetMem с последующим FreeMem, что то вроде
GetMem(p, 8);
FreeMem(p, 16);
напрочь сбивают с толку делфийский менеджер кучи, и после таких шедевров могут быть траблы, похожие на описанные выше, тот же эксепшен в безобидном конструкторе безобидного класса.
← →
Digitman (2004-01-29 16:15) [34]
> Ihor Osov"yak © (29.01.04 16:10) [33]
да нет) ... чудеса, думаю, всегда бывают, когда ищешь не там где потерял, а там где светлей)
← →
YuRock (2004-01-29 16:32) [35]> Digitman © (29.01.04 16:15) [34]
> Чудеса всегда бывают, когда ищешь не там где потерял, а там где светлей
Красивый афоризм. Надо будет запомнить.
← →
alexEagle (2004-01-29 16:35) [36]Спасибо всем кто ответил, решение проблемы я уже нашел.
На самом деле оказалось, что я допустил классическую ошибку С++-программиста, пишущего на делфи - забыл вызвать inherited Destroy в деструкторе дочернего для frmTable окна. Именно поэтому вылетало исключение впоследствии.
Ну не могу я привыкнуть к тому, что кроме того что вручную нужно вызывать деструктор, так еще и в деструкторе вручную нужно прописывать inherited Destroy.
← →
Digitman (2004-01-29 16:51) [37]
> забыл вызвать inherited Destroy в деструкторе дочернего
> для frmTable окна
поясни ...
о каком inherited Destroy и о каком "дочернем окне" может идти речь, если ты пытаешься создать "абсолютно чистую" форму и на этапе конструирования ты получаешь граблями ?
т.е о каком диструкторе м. идтим речь, если конструирование еще идет, и в нем нет ничего, что бы могло хоть как-то вести к "криминалу", уводящему в разрушение при исключении в констр.методе ??
сие есьм премного любопытно)...
← →
sniknik (2004-01-29 17:09) [38]а как же
alexEagle © (29.01.04 14:03) [29]
> TForm.Create(nil).ShowModal;
> выдает ту же ошибку
← →
alexEagle (2004-01-29 17:09) [39]На самом деле ошибка происходила не при создании окна, а через некоторое время после вызова деструктора frmTableItem, который создавался как дочернее окно для frmTable. поскольку происходила ошибка при работе с памятью то приложение падало не сразу а через некоторое время, и поскольку брэкпойнт стоял именно на создании frmTable, то падало именно тогда. Как оказалось впоследствии , оно могло падать и дальше и ближе. Все зависит от того где и что было запорото, но в последнем сообщением об ошибке все равно был указан адрес 00000000 поскольку если предыдущие можно было игнорировать то в этому случае двигаться видимо было некуда.
Экспериментально добивался работы программы на несколько секунд если оставлял MessageBox после окончания всех действий в процедуре ShowDispensers.
Одним словом, ребяты, не забывайте что ООП в делфи корявенькое!
← →
sniknik (2004-01-29 17:11) [40]> Одним словом, ребяты, не забывайте что ООП в делфи корявенькое!
а ты без колес ездить не пытался? оправдываясь тем что привык на катере...
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.02.10;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.008 c