C ++使用异常

时间:2017-06-06 16:32:30

标签: c++

我有一个简单的问题

如果我有一个try和catch的代码,就像这样

try
{
...
}
catch(exception& ex)
{
   AfxMessageBox(ex.what());
}

这会捕获所有异常,甚至是坏指针等异常吗?而且,如果此代码存在,例如,代码有指针或内存问题,它仍会崩溃吗?或者我必须使用

catch(...)

但是,我怎样才能确切地指出是什么原因导致了一场不合时宜的撞击呢?

3 个答案:

答案 0 :(得分:3)

如果您的代码具有未定义的行为,则可能导致几乎任何事情发生,包括抛出异常。

Visual C ++ 6(默认情况下)将某些操作系统级别的异常转换为C ++异常,正如您在此处讨论的那样。它显然没有很好地解决 - 他们的新编译器默认情况下执行此操作。如果你真的想要这种行为,他们确实提供了一个编译器开关(例如,/ EHa),可以让你这样做 - 但大多数人可能不建议使用它。

Windows结构化异常处理有一个SetUnhandledExceptionHandler,它可以让你捕获SEH异常,找出你抓到的异常,然后抛出你认为适合表示什么的C ++异常。发生了。然而,这是一个相当手动的过程(即,您可以编写类似switch语句的东西来整理您已经捕获的结构化异常,并决定要响应的C ++异常。这一点)。

同样,在Linux上,您可以为各种信号设置处理程序,并抛出异常以响应它们。你可能需要对此有点棘手。问题是POSIX信号是异步传递的,并且你在中非常限制了你可以做的事情。信号处理程序本身唯一能做的就是设置sig_atomic_t类型的标志,外部代码可以(方便时)检查其值,如果设置了,则抛出异常。混合信号和例外通常是一项非常重要的工作。

catch(...)而言,它只会捕获C ++异常,所以它只会捕获内存问题,如上所述,如果你将它与某种翻译一起使用从结构化异常/信号中创建C ++异常。至于你在那里可以做什么:它真的非常有限。您无法获得有关发生的异常的任何信息。至少在我使用它的时候,尝试尽可能有序地管理关闭几乎是最后的事情,仅仅因为在它进入的时候,任何更聪明的事情的可能性在更具体的处理程序中已经筋疲力尽。

答案 1 :(得分:1)

似乎对不同类型的错误存在混淆,所以这里是对不同错误的解释以及如何处理它们。可能发生三种错误

  1. 编译错误
  2. 由于触发未定义的行为而导致的运行时错误
  3. 系统限制导致的运行时错误
  4. 以下是您需要对这三个

    执行的操作

    编译错误您的编译器是您的朋友。修复你的代码,但尽量避免绕过类型系统。

    触发未定义的行为您的代码中某处似乎存在此类问题。在这种情况下,您有一个运行时错误。你可能做了什么

    1. 取消引用无效指针
    2. 执行整数除以零
    3. 使用了不受支持的程序集级指令
    4. 将已释放的指针传递给free
    5. 要查找解决方案1-3之类的问题,请使用调试器。 assert宏也很有用。请注意,如果未能检查某些分配系统资源的函数是否失败,则可能会引入类型1的问题。如果是这样,请参阅由于系统限制而导致的运行时错误

      类型4的问题很难找到,因为您会在下一个malloc时发现问题。在GNU / Linux上,通过valgrind运行程序是最安全的选择。我对此没有任何关于Windows工具的知识。

      由于系统限制导致的运行时错误这是您使用例外的地方。您无法预见用户指定的文件不存在,或者以不可解码的方式编码。或者您尝试调出OpenGL,但用户没有最新的图形驱动程序,或者您使用的是远程X11连接。要“解决”这些问题,请检查系统级别的返回值,并通过异常进行挽救,这将由最近的catch语句捕获。

答案 2 :(得分:-1)

std :: exception只会处理这类异常。http://en.cppreference.com/w/cpp/error/exception。 如果你不确定你的尝试块可以抛出什么样的异常,而你不想终止你的过程,你可以盲目地去捕获(...)。 如果你知道你的try块可以抛出什么样的异常,并且所有异常都在std :: exception下,那就去吧。