C++中的分段错误是否可以像在 Java 中处理 NullPointerExceptions 一样处理

Can segmentation faults in C++ be handled in the same way as NullPointerExceptions would be handled in Java?

本文关键字:处理 NullPointerExceptions 一样 Java 错误 分段 是否 C++      更新时间:2023-10-16

我意识到在分段错误(C++(和NullPointerExeception(Java(之后,计算的状态实际上被破坏了,但这并不意味着整个应用程序应该关闭。在一个设计良好的内聚系统中,其他计算应该能够成功完成,提供所需的结果。

在Java中,我们简单地捕获NullPointerException,并在可能的情况下跳过计算。在C++中也能达到同样的效果吗?即对于计算,我们是否可以定义在分段错误(由特定计算导致(之后执行的特定代码,其方式与 Java 中使用的 try catch 块大致相同?

一个简单的例子是在事件循环中,如果其中一个事件导致 seg 错误,请跳到处理下一个事件。

另一个例子是在算法交易中,您将暂停订单的执行并允许交易者手动接管,而不会使整个系统崩溃并破坏所有其他订单。

所以我正在寻找C++代码,它以与下面的 NullPointerException 相同的方式处理 seg 错误。

try {
   computation();
} catch (NullPointerException e){
   // specific code for handling the problem in the above execution of computation();
}

TL;DR:一般来说答案是否定的。但是有一些特定于系统的方法可以处理此类异常情况。

让我先解释一下"no"部分。 C++在取消引用空指针或其他分段错误的情况下不会引发异常。这些错误的处理方式与越界数组访问相同 - 不检查任何内容,只是执行代码。程序员负责确保不会遇到此类错误 - 例如,可以在使用前显式检查指针是否为 null。

在大多数系统中,底层硬件和操作系统机制不允许访问,例如,当取消引用空指针时,会因分段错误而停止程序。但是有些系统取消引用空指针不会导致分段错误。无论如何处理此类情况,C++都不会(而且很可能永远不会(包含检查它们并抛出异常的机制。

仍然有一些依赖于系统的方式来处理这种情况,例如 *nix 系统中的信号,Windows 中的 SEH。

我意识到在分段错误后计算状态实际上已损坏

分段错误表示您有一个错误,您的应用程序可能无法从中恢复。 但我认为这不会破坏记忆,因为这不能改变记忆。 这可能表明您的内存之前已损坏。

在C++中可以达到相同的效果吗?即对于计算,我们是否可以定义在分段错误(由特定计算导致(之后执行的特定代码,其方式与 Java 中使用的 try catch 块大致相同?

从理论上讲,这可能是可能的。 C++现在支持例外。 恕我直言,C++可以做Java所做的任何事情,问题是他们是否愿意这样做。 在实践中,我不认为这将作为标准实施。

在设计良好的内聚系统中,应用程序必须终止

虽然我同意这一点,但在 Java 中,您对应用程序的定义有一定的灵活性。 例如,一个 Java 进程可以在其中运行多个应用程序,这些应用程序可以在运行时加载、卸载和升级。 严重错误可能会导致其中一个应用程序无法使用,但这并不意味着整个过程必须死亡。

我不确定这是否可以通过 C++ 中的异常捕获机制来完成,但这可以在具有 sigactionPOSIX兼容系统上实现,这允许您在收到某个信号时调用函数

信号处理示例

是的,你可以这样做。根据我的经验,我有时会发现失败的操作会导致未来的操作相当无用(因为它们正在对应该由失败的操作更新但事实并非如此的数据进行操作(,或者许多操作由于相同的原因而失败。但有时它确实允许大多数正确的程序执行。

为了能够捕获分段错误,您需要做一些特定于编译器/操作系统的事情,但我认为这是一个不同的问题。

对于C++来说,唯一好的解决方案是修复代码,如果不能,其他答案中解释的信号处理是有风险的,但也许它有效。

如果我必须管理一个段错误的程序,我的首选解决方案是为错误代码创建一个单独的进程。这样,该过程可以自由崩溃,并从安全进程中重新启动或清除。