C ++: стек не разматывается при возникновении исключения - PullRequest
1 голос
/ 05 ноября 2010

Привет,

У меня довольно странная проблема в одном из моих проектов на C ++: Я написал оболочку C ++ Socket, которая пытается подключиться к данному хосту и порту (через IPv4 / TCP) и выдает исключение SocketException (полученное из std :: runtime_error), если возникает ошибка (например, «Отказано в соединении»). Исключение перехватывается правильно, и сообщение об ошибке записывается в консоль, как и ожидалось, но, очевидно, деструктор моего класса Socket не вызывается (он должен также выводить сообщение в std :: cerr, но сообщение появляется только в том случае, если соединение работает и Сокет уничтожается позже, если он выходит из стека, например, в конце функции, которая пытается использовать сокет). Деструктор должен закрыть инкапсулированный сокет, но при исключении выброшенный сокет остается открытым (вы можете увидеть его с lsof как сокет неизвестного типа), поэтому кажется, что никакой код в деструкторе вообще не выполняется). Поскольку я не мог воспроизвести эту проблему с помощью простого тестового примера, я предполагаю, что это как-то связано с довольно сложной структурой моего проекта: у меня есть базовое приложение, содержащее код для класса Socket и предоставляющий класс Singleton, который предлагает методы, которые реализуют протокол, используемый для связи, и возвращают результаты запроса, каждый вызов одного из этих методов генерирует свой собственный экземпляр Socket и предоставляет ему необходимую информацию о хосте и порте для использования. Чтобы упростить генерацию и управление сокетами, используется std :: auto_ptr, который должен удалить Socket, если метод завершен, и стек очищен, который работает должным образом в соответствии с выводом консоли, но он должен работать так же, как и при генерируемом исключении, по крайней мере, таково было мое мнение до сих пор. Ядро может загружать плагины в формате общего объекта с помощью dlopen и получает указатель на экземпляр класса плагина через внешнюю объявленную C-функцию в общем объекте. Этот экземпляр теперь использует Singleton, предоставленный ядром, для связи с сервером и отображения полученных данных.

У меня вопрос: есть ли ограничения на раскручивание стека при использовании общих объектов или где я должен искать то, что упустил, чтобы эта работа работала правильно?

Ответы [ 3 ]

7 голосов
/ 05 ноября 2010

Если ваше исключение выдается из конструктора, деструктор не будет вызван.

0 голосов
/ 05 ноября 2010

Если вы программируете на Linux, возможно, вы вызываете проблему, при которой исключение, генерируемое из общей библиотеки, не перехватывается должным образом (проблема с определением типа исключения).Эта проблема объяснена здесь и здесь , и я уверен, что вы могли бы погуглить больше страниц, объясняющих ту же проблему.ищу решение: (

0 голосов
/ 05 ноября 2010

Хорошо, забудь об этом.Другой взгляд на код показал, что существует вероятность того, что исключение могло быть вызвано уже в конструкторе, чтобы деструктор не был вызван, как это описано в стандарте C ++.Не бросая в конструктор решил проблему.Вот что программирование на Java делает с вашими навыками C ++ ^^ Извините, пожалуйста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...