Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.10;
Скачать: CL | DM;

Вниз

Почему падает 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.014 c
1-29380
SGU_
2004-01-29 05:51
2004.02.10
Закрытие процесса EXCEL


1-29379
WG
2004-01-23 13:31
2004.02.10
Как прицепиться к уже открытому в Excel файлу ?


1-29437
Yarcev
2004-01-30 12:55
2004.02.10
Отчеты


1-29339
Сергей Уфимский
2004-01-29 15:20
2004.02.10
Cохранение массива в файл.


3-29231
guest_Dmitry
2004-01-19 16:15
2004.02.10
Формат поля numeric