Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > вылетает ошибка при закрытии приложения


Автор: scroollocker 22.7.2011, 23:42
Пишу джаббер клиент и столкнулся с неизвестной, и ранее мне не встречавшейся проблемой. При закрытии программы, возникает ошибка 
Цитата

EAccessViolation with message 'Access violation at address xxxxxxx. Read of address zzzzzzzz'
 
прошелся в деббагер до этой ошибки, она оказалась в файле "GETMEM.INC". И что еще удивительно, это то, что при включении use dynamic RTL и отключенном runtime packages ошибка исчезает. Мистика или какая то изученная вещь?  smile  Направте меня на путь джедая.

Автор: borisbn 23.7.2011, 09:25
Цитата(scroollocker @  22.7.2011,  23:42 Найти цитируемый пост)
Мистика или какая то изученная вещь?

Второе.
Отключение use dynamic RTL говорит компилятору включить менеджер памяти (ф-ции выделения и освобождения памяти) непосредственно в exe-шник (или dll-ку). Если exe-шник использует какие-либо dll-ки, которые собраны с флажком use dynamic RTL, то в программе получается 2 менеджера памяти - один внешний (borlandmm.dll), второй - вшитый в exe. Может возникнуть ситуация (а она, судя по всему и возникает), в которой один менеджер выделил память, а второй пытается освободить.
Такое может быть и если в dll-ке отключен use dynamic RTL - всё равно 2 менеджера - один встроен в exe, другой - в dll.

Короче, отключать use dynamic RTL можно только если у тебя простейшая helloWord'ная программа. Чуть сложнее - низя.

Автор: scroollocker 23.7.2011, 22:37
borisbn, то что изучено, это меня радует  smile 

Но, Из всех наворотов использую только Борландовский TClientSocket. Кстати, после открытия соединения с сервером, и начала обмена информацией, если закрыть программу, вылетает эта ошибка. В итоге получается, что то в нем? 
Цитата

отключать use dynamic RTL можно только если у тебя простейшая helloWord'ная программа. Чуть сложнее - низя.

Получается, чтобы мне перенести программу на другой комп, надо в обязательном порядке тащить какие то доп. файлы? Вроде же, можно обойтись без этого? 

Автор: artsb 24.7.2011, 01:10
Мне кажется, что вы пытаетесь обратиться к какому-то объекту во время разрушения формы.
Проверьте все свои деструкторы на наличие таких обращений. Так же, если вы переопределили оконную процедуру, то при обработке событий, лучше всё обернуть в:
Код

if(!this->ComponentState.Contains(csDestroying)) {
// do
}

Плюс, при закрытии формы, нужно останавливать все закачки и потоки (особенно те, из которых идёт обращение к VCL).

Автор: xvr 24.7.2011, 12:20
Цитата(borisbn @  23.7.2011,  09:25 Найти цитируемый пост)
Короче, отключать use dynamic RTL можно только если у тебя простейшая helloWord'ная программа.

Или если программа не использует никаких dll (ну кроме системных  smile ), как видимо у ТС и есть  smile 

Цитата(scroollocker @  22.7.2011,  23:42 Найти цитируемый пост)
прошелся в деббагер до этой ошибки, 

А что в стеке до GETMEM.INC ?

Автор: scroollocker 24.7.2011, 23:25
artsb,
Сейчас пробегусь по коду, проверю все еще раз. Может действительно допустил где то ошибку, портящую мне жизнь теперь.

xvr

Цитата

А что в стеке до GETMEM.INC ?
 

А где смотреть? в "Call stack"? перед тем как действие перешло в getmem.inc?

И еще, если например не делать ClientSocket->Open(); закрывается нормально, без ошибок.

Автор: artsb 24.7.2011, 23:39
Цитата(scroollocker @  24.7.2011,  23:25 Найти цитируемый пост)
И еще, если например не делать ClientSocket->Open(); закрывается нормально, без ошибок. 

Похоже, что у вас ClientSocket работает в отдельном потоке. И вы этот поток не останавливаете при закрытии формы. А в обработчиках ClientSocket, у вас идёт обновление какого-нибудь Label'а. И происходит так, что Label уже "умер", а поток пытается до него достучаться.
Плюс проверьте обработчики событий ClientSocket.

Автор: Dem_max 25.7.2011, 15:18
Цитата

Короче, отключать use dynamic RTL можно только если у тебя простейшая helloWord'ная программа. Чуть сложнее - низя.

глупости все это.

Автор: borisbn 25.7.2011, 16:15
Цитата(Dem_max @  25.7.2011,  15:18 Найти цитируемый пост)
глупости все это.

а вот такое заявление - без единого аргумента - не глупость ?

Автор: Dem_max 25.7.2011, 16:27
это никак не влияет на AV

Автор: xvr 25.7.2011, 17:09
Цитата(scroollocker @  24.7.2011,  23:25 Найти цитируемый пост)
А где смотреть? в "Call stack"?

Именно. В момент слома.

Автор: borisbn 25.7.2011, 17:45
Цитата(Dem_max @  25.7.2011,  16:27 Найти цитируемый пост)
это никак не влияет на AV

когда один менеджер памяти удаляет память, выделенную в другом - может быть что угодно... у него элементарно для этого указателя в какой-нибудь своей таблице может быть прописан другой размер...

Автор: Dem_max 25.7.2011, 17:55
Цитата

когда один менеджер памяти удаляет память, выделенную в другом - может быть что угодно

а такое происходит когда программер код через одно место сваял

Автор: borisbn 25.7.2011, 18:05
Цитата(Dem_max @  25.7.2011,  17:55 Найти цитируемый пост)
а такое происходит когда программер код через одно место сваял

пример: основная программа передаёт в dll-ку свой TForm в качестве Parent'а и Owner'а. В dll-ке создаётся TFrame, который кладётся на Parent'а и делает его своим Owner'ом. По окончании программы Owner удаляет всех "детей", в том числе и того, который создан в dll. Если отключить use dynamic RTL, то в dll-ке память под TFrame выделит свой менеджер, а удалит его в основной программе - другой. При включенном же use dynamic RTL всё будет делать один манагер.
Такой способ Ownership-ства - вполне стандартная вещь в VCL, и тот, кто его использует - вовсе не криворукий. Вот VCL-ю не мешало бы проверять, чтоб такой ситуации с двумя менеджерами не было в принципе. Не знаю как... в других системах ведь как-то проверяют

Автор: Dem_max 25.7.2011, 18:13
если в dll создается объект, там он и должен быть уничтожен 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)