| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Обработка исключения |
| Автор: Peter 8.1.2006, 22:24 | ||||||
Конкретно дело обстоит так. Многооконное приложение; каждое дочернее окно - объект класса <КлассДокумента>. Когда дочернее окно открыто, в объекте этого класса может выполняться некоторая операция (функция F вызывается по таймеру). В функции F используется переменная x - член класса <КлассДокумента>, имеющий тип "указатель на структуру S". В конструкторе <КлассДокумента>
в деструкторе
Рассмотрим следующую ситуацию (которая наблюдалась в работе программы): в момент выполнения функции F пользователь закрывает окно. В деструкторе уничтожается объект, на который указывает x, и в то же самое время x используется в F. Если ничего не предпринимать, то программа вылетает. Может ли что-нибудь испортиться, если я заключу тело F в
?????????????? Не повредится ли, например, стэк? |
| Автор: Mayk 8.1.2006, 23:07 | ||||||
| А может стоит воспользваться чем-нибудь типа shared_ptr, или еще каким имеющимся классом для подсчета ссылок? В крайнем случае накатать самому.
Если приложение многопоточное, и деструктор вызовется не из того потока, в котором выполняется F, то может прийти Большой Ой. Добавлено @ 23:12
А что нам это даст?
завершается нормально |
| Автор: chipset 8.1.2006, 23:21 |
| Курим MSDN на тему синхронизации потоков или используем метод подсчета ссылок как правильно подметил Mayk |
| Автор: Peter 9.1.2006, 12:49 | ||||||||
Первое нам даст то, что при выполнении F программа не вылетит. Второе не подходит (наверно, имелось в виду
Синхронизация потоков, конечно, это хорошо, но слишком долго, и в ней нет необходимости, поскольку результат работы функции F пользователя уже не интересует. А поставить try-catch - это дело нескольких секунд. Вопрос лишь в том, не может ли быть от этого побочных эффектов? |
| Автор: Mayk 9.1.2006, 16:32 | ||||||||||
Ага
Да ну? Вы СЛИШКОМ высокого мнения об исключениях. В мной указаном примере произошла запись в уже удаленный s. И исключения не возникло(откуда? кто будет кидать исключение? система? а как она узнает что память освобождена?). Точно так же оно не возникнет если в Вашей программе удалить объект из другого потока:
Исключения не связаны с синхронизацией потоков. Исключения не возникают, когда происходит запись не туда куда надо. Исключения не вознакают, когда происходит чтения из разрушенного/(что еще хуже) полуразрушенного объекта. Чтобы поймать исключения, его нужно кинуть Исключение не может быть поймано, если оно не брошено. Кстати. В качестве альтернативы. Грубешая и не правильная синхронизация может выглядеть так:
И наблюдаем за крахом, в тот момент, когда один поток начнет выполнять F, прервется до x->doNotDeleteMe = true;, передаст управление другому потоку, который благополучно разрушит x. ОЙ.
В ней (или в альтернативе из подсчёта ссылок => позднего удаления) есть необходимость. Иначе программа умрёт. |
| Автор: Earnest 9.1.2006, 17:35 |
| Синхронизация и подсчет ссылок - это не альтернативы, а Необходимые Вещи (причем обе сразу). Впрочем, вместо подсчета ссылок можно придумать какой-нибудь другой механизм управления владением и временем жизни. Но подсчет ссылок - наиболее простой и естественный в данном случае, ИМХО. Но если есть разные потоки, работающие с одними и теми же данными, в синхронизации всегда есть необходимость! В данном случае это касается возможной реализации shared_ptr - придется позаботиться о том, чтобы все его методы были потокобезопасны (скажем, инкремент-декремент числа ссылок должен быть атомарным, и т.д.). Иначе твоя программа будет работать или валиться в зависимости от погоды на Галапагосских островах. |
| Автор: Peter 9.1.2006, 21:02 | ||||||
Специально для проверки ставил
и сообщение в message-box было благополучно показано, а программа продолжала работать.
Ищу дешевый способ починить программу. Если не найду, придется делать синхронизацию потоков. |
| Автор: threef 9.1.2006, 21:19 | ||
| Стек не повредится, x указывает на кучу. Как у тебя происходит управление функцией F , вернее, таймером ? Если таймер привязан к существовании этого дочернего окна, то просто убей его в OnDestroy этого окна. Если у тебя функция по таймеру очень медленная, ( в процессе ее однократного выполнения пользователь может открыть и закрыть окно) , то все равно в однопотоковом приложении этого просто не произойдет
Примечание: при использовании многопоточности действительно могут возникнуть всякие ОЙ, этим методом пользоваться нельзя. |
| Автор: Peter 9.1.2006, 23:01 | ||
Приложение многопоточное.
|