繁体   English   中英

C ++:堆栈不会在引发异常时解开

[英]C++: Stack is not unwound on exception thrown

哈o

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

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

如果构造函数引发了异常,则不会调用析构函数。

好吧,忘了那个。 代码中的另一处外观显示,很可能已经在构造函数中引发了异常,因此就不会调用析构函数,如C ++标准中所述。 不抛出构造函数即可解决问题。 这就是Java编程对您的C ++技能所做的事情。^^请原谅。

如果在Linux上进行编程,则可能会引发一个问题,即无法正确捕获从共享库引发的异常(确定异常类型的问题)。 这个问题在这里这里都得到了解释,我相信您可以在Google上搜索更多页面来解释这个问题。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM