C++ 无法从堆栈对象捕获异常

C++ 无法从堆栈对象捕获异常,c++,exception,pointers,stack,heap,C++,Exception,Pointers,Stack,Heap,希望你今天过得愉快 我正在编写一个类来包装Berkley C Networking API,到目前为止,我只运行了一个TCP服务器/客户端 具有讽刺意味的是,我遇到的问题不是网络,而是堆栈和堆。也许我只是不完全理解它,但当我使用以下内容时: ClientSocket*mysock=newclientsocket(); 只需使用->操作符调用函数,它就可以很好地工作——如果发生错误,我的SocketException类将不会出现问题 但是,当我使用: clientsocketmysock;

希望你今天过得愉快

我正在编写一个类来包装Berkley C Networking API,到目前为止,我只运行了一个TCP服务器/客户端

具有讽刺意味的是,我遇到的问题不是网络,而是堆栈和堆。也许我只是不完全理解它,但当我使用以下内容时:

ClientSocket*mysock=newclientsocket();
只需使用->操作符调用函数,它就可以很好地工作——如果发生错误,我的SocketException类将不会出现问题

但是,当我使用:

clientsocketmysock;
并且在使用调用函数时会引发任何异常。操作员,它显示:

在抛出“SocketException”实例后调用terminate
流产
然后把我扔回一个终端提示符

忘记添加,我正在将调用包装在try/catch块中

我知道第一个示例使用'new'关键字返回指向堆上新ClientSocket实例的指针,第二个示例用于堆栈,但我不知道问题所在

我认为我遗漏了一些关于指针/引用/堆栈/堆的信息,但我不知道发生了什么。代码通常运行正常,但如果引发任何异常….>:(

编辑:在链接页面上,Client.cxx和Server.cxx是示例文件!谢谢您指出这一点,Eric。 在此方面的帮助将不胜感激。此项目的来源是:
指向所有文件的链接:
(我不能粘贴超过2个链接,我有4个文件,所以在有人可以将链接合并到我的帖子之前,我必须这样做) 注意:Socket.cxx相当大,因为它包含ServerSocket、ClientSocket和SocketException定义

编译上述所有文件的命令为:
g++-c Socket.cxx-o Socket.o
g++-c Server.cxx-o Server.o
g++-c Client.cxx-o Client.o
g++服务器.o套接字.o-o服务器
g++客户机.o套接字.o-o客户机

谢谢


小更新,按照Jon的建议,我查阅了socket函数的文档,现在它有了更好的错误报告-我检查'errno'变量并基于此抛出一个异常。(我没有将其设置为非阻塞…;)-只是想更新并说声谢谢!:D

对我来说,这听起来像是出于合法原因引发的异常,在堆栈展开过程中,一些对象(可能是
ClientSocket
)析构函数抛出异常。由于运行时无法以任何有意义的方式解决这种情况(同时“抛出”两个异常),因此会调用
terminate
函数并关闭程序

未回答的问题是,如果在堆栈上分配了析构函数所属的对象,为什么某些析构函数会抛出。但要回答这个问题需要更多的数据。也许你可以再深入一点来验证我的假设

顺便说一句,如果情况确实如此,并且由于没有析构函数应该这样做,我们可以得出结论,违规类存在致命缺陷

更新:似乎我在花钱

您的类
Socket
的析构函数调用
close
,并且
close
可以抛出。这是一个严重的编程错误。您应该将
close
调用包装在析构函数中

try {
    close();
}
catch(...)
{ /* this space intentionally left blank */ }
然后坠机就会消失

第二次更新(不再崩溃)


如果
recv
返回-1,这意味着套接字处于非阻塞模式,当前没有可接收的数据。这不是一个错误,而是一个特性。你不应该在那里抛出异常。您应该做什么完全取决于您是想在阻塞模式还是非阻塞模式下使用套接字。

对我来说,这听起来像是出于合法原因引发的异常,并且在堆栈展开过程中,一些对象(可能是
ClientSocket
)析构函数抛出异常。由于运行时无法以任何有意义的方式解决这种情况(同时“抛出”两个异常),因此会调用
terminate
函数并关闭程序

未回答的问题是,如果在堆栈上分配了析构函数所属的对象,为什么某些析构函数会抛出。但要回答这个问题需要更多的数据。也许你可以再深入一点来验证我的假设

顺便说一句,如果情况确实如此,并且由于没有析构函数应该这样做,我们可以得出结论,违规类存在致命缺陷

更新:似乎我在花钱

您的类
Socket
的析构函数调用
close
,并且
close
可以抛出。这是一个严重的编程错误。您应该将
close
调用包装在析构函数中

try {
    close();
}
catch(...)
{ /* this space intentionally left blank */ }
然后坠机就会消失

第二次更新(不再崩溃)


如果
recv
返回-1,这意味着套接字处于非阻塞模式,当前没有可接收的数据。这不是一个错误,而是一个特性。你不应该在那里抛出异常。您应该做什么完全取决于您想在阻塞模式还是非阻塞模式下使用套接字。

Jon已经解决了终止问题,但原始代码中还有另一个问题


动态分配的对象似乎可以工作的原因是,当其他地方出现异常时,它会泄漏,并且不会调用析构函数。虽然这避免了双重异常问题,但它会在以后导致另一个集合…

Jon已经解决了终止问题,但原始代码中还有另一个问题


动态分配的对象似乎可以工作的原因是,当其他地方出现异常时,它会泄漏,并且不会调用析构函数。虽然这避免了双重异常问题,但它会在稍后导致另一个集合…

编写一个小测试用例来再现该问题,并包括