C ++:抛出异常时堆栈不会被解除

时间:2010-11-05 12:11:52

标签: c++ exception object shared

你好,

我的一个C ++项目中有一个非常奇怪的问题: 我编写了一个C ++ Socket包装器,它尝试连接到给定的主机和端口(通过IPv4 / TCP)并抛出SocketException(派生自std :: runtime_error),如果发生错误(例如'Connection refused')。正确捕获异常,并按预期将错误消息写入控制台,但显然我的Socket类的析构函数未被调用(它也应该向std :: cerr输出消息,但只有连接有效时才会显示消息如果Socket离开堆栈,稍后会被销毁,例如在尝试使用套接字的函数结束时。析构函数应该关闭封装的套接字,但是在抛出异常时套接字保持打开状态(你可以用lsof作为未知类型的套接字看到它),因此析构函数中似乎根本没有执行任何代码。 由于我无法用一个简单的测试用例重现这个问题,我的猜测是它在某种程度上与我项目的相当复杂的结构有关:我有一个核心应用程序包含Socket类的代码并提供一个Singleton类提供实现用于通信的协议并返回请求结果的方法,对这些方法之一的每次调用都会生成自己的Socket实例,并为其提供有关要使用的主机和端口的必要信息。为了简化套接字生成和管理,使用std :: auto_ptr,如果方法已经完成并且清理了堆栈,它应该删除Socket,这可以根据控制台输出正常工作,但它应该在抛出异常时以相同的方式工作,至少到目前为止我的意见是什么。 核心能够通过dlopen以共享对象格式加载插件,并通过共享对象中的extern C声明函数获取指向插件的类实例的指针。 此实例现在使用核心提供的Singleton与服务器通信并显示检索到的数据。

我的问题是:在使用共享对象时,堆栈展开是否存在限制,或者我应该在哪里查找错过的内容以使其正常工作?

3 个答案:

答案 0 :(得分:7)

如果从构造函数抛出异常,则不会调用析构函数。

答案 1 :(得分:0)

好的,别忘了那个。代码中的另一个外观表明,有可能在构造函数中已经抛出异常,因此不会调用析构函数,正如C ++标准中所描述的那样。没有投入构造函数解决了问题。这就是Java中的编程对你的C ++技能的影响^^ 请原谅噪音。

答案 2 :(得分:0)

如果您在linux上编程,则可能会触发一个问题,即从共享库中抛出的异常未被正确捕获(异常类型确定的问题)。这个问题已解释为herehere,我相信您可以在谷歌上搜索更多解释相同问题的网页。

如果这是一个问题,我仍在寻找解决方案:(