这个问题在这里已经有答案了:

  try {
        int* p = 0;
        *p = 1;
    } catch (...) {
        cout << "null pointer." << endl;
    }

我试图像这样捕获异常,但它不起作用,有什么帮助吗?

有帮助吗?

解决方案

C++ 中不存在“空指针异常”这样的东西。您可以捕获的唯一异常是显式抛出的异常 throw 表达式(另外,正如 Pavel 指出的那样,标准 C++ 本质上抛出的一些标准异常) operator new, dynamic_cast ETC)。C++ 中没有其他例外。取消引用空指针、除以零等。在 C++ 中不会生成异常,它会生成 未定义的行为. 。如果您希望在此类情况下引发异常,则您有责任手动检测这些情况并执行以下操作 throw 明确地。这就是 C++ 中的工作原理。

无论您似乎在寻找什么,都与 C++ 语言无关,而是特定实现的功能。例如,在 Visual C++ 中,系统/硬件异常可以“转换”为 C++ 异常,但这种非标准功能是有代价的,通常不值得付出代价。

其他提示

你不能。取消引用空指针是系统事务。

在 Linux 上,操作系统会在您的应用程序中发出信号。看一眼 信号 查看如何处理信号。要“捕获”一个,您需要挂钩一个函数,该函数将在以下情况下被调用 SIGSEGV. 。在这里,您可以尝试在正常终止程序之前打印一些信息。

Windows 使用 结构化异常处理. 。你可以使用 instristics __try/__except, ,如上一个链接中所述。我在我编写的某个调试实用程序中执行此操作的方法是使用该函数 _set_se_translator (因为它与钩子紧密匹配)。在 Visual Studio 中,确保启用了 SEH。使用该函数,您可以挂钩一个函数,以便在系统在应用程序中引发异常时调用;在你的情况下它会调用它 EXCEPTION_ACCESS_VIOLATION. 。然后,您可以抛出异常并将其传播回来,就像首先抛出异常一样。

取消引用空值(或超出数组末尾的指针,或随机无效指针)会导致未定义的行为。没有可移植的方法来“捕获”它。

有一种非常简单的方法可以捕获任何类型的异常(除以零、访问冲突等) 视觉工作室 使用 try -> catch (...) 块。

一个小的项目调整就足够了。只需启用 /EHa 项目设置中的选项。看 项目属性 -> C/C++ -> 代码生成 -> 将启用 C++ 异常修改为“Yes With SEH Exceptions”. 。就是这样!

请参阅此处的详细信息:http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx

C++ 不进行指针检查(尽管我认为某些实现可以)。如果您尝试写入空指针,它很可能会严重崩溃。它不会抛出异常。如果你想捕获这个,你需要在尝试写入指针之前自己检查指针的值。

一般来说你不能。即使你可以,这也就像试图在发生泄漏的潜艇上贴创可贴一样。

一个瘫痪的应用程序造成的损害比崩溃的应用程序要大得多。我的建议是让它崩溃,然后修复崩溃的原因。冲洗。重复。

正如其他人所说,你不能在 C++ 中做到这一点。

如果我可以提出更广泛的观点:即使在允许您捕获它的语言中,更好的操作也是不要触及空指针。当错误已经在你面前爆炸时发现它,然后决定继续前进,就像它没有发生一样,这并不是一个好的编码策略。像空指针取消引用、堆栈溢出等事情应该被视为灾难性事件并防御性地避免,即使您的语言允许您以不同的方式对其做出反应。

没有独立于平台的方法可以做到这一点。在 Windows/MSVC++ 下你可以使用 __尝试/__除了

但无论如何我都不建议这样做。您几乎肯定无法从分段错误中正确恢复。

如果你愿意,你可以自己检查指针并抛出......

if (p == nullptr) throw std::exception("woot! a nullptr!")
p->foo();

所以当然这只是为了调试问题, nullptr 一开始就不应该发生:)

简短的回答 - 你不能以可移植或标准的方式,因为这样的错误可能会破坏进程本身。

长答案 - 你可以做的比你想象的更多,而且绝对比程序崩溃的默认情况更多。但是,您需要记住三件事:
1)这些错误比异常更严重,并且通常不能作为逻辑异常出现。
2)即使您可以为公共使用提供干净的抽象接口,您对它们的检测和库处理将取决于后端的平台。
3)总会有一些严重的崩溃,你甚至无法在结束之前检测到它们。

基本上,诸如段错误或堆损坏之类的错误也不例外,因为它们会破坏运行程序的实际进程。您在程序中编写的任何内容都是程序的一部分,包括异常处理,因此除了在进程终止之前记录一条漂亮的错误消息之外,任何其他内容都是不可取的,在少数情况下,这并非不可能。在 POSIX 中,操作系统使用信号系统来报告此类错误,并且您可以注册回调函数以在退出之前记录错误。在 Windows 中,操作系统有时可以将它们转换为看起来正常的异常,您可以捕获这些异常并从中恢复。

然而,最终,您最好的选择是编写防御性代码来应对此类噩梦。在任何给定的操作系统上,都会有一些问题非常糟糕,以至于您无法在进程终止之前检测到它们,即使原则上也是如此。例如,损坏您自己的堆栈指针可能会导致您严重崩溃,甚至您的 POSIX 信号回调也看不到它。

在 VC++ 2013(以及早期版本)中,您可以在异常上放置断点:

  1. 按 Ctrl + Alt + Delete(这将打开异常对话框)。
  2. 展开“Win32 例外”
  3. 确保检查“0xC0000005 访问冲突”异常。

现在再次调试,当空取消引用发生时,将准确命中断点。

C++ 中不存在 NULL 指针异常,但您仍然想捕获相同的异常,那么您需要为其提供自己的类实现。

下面是相同的示例。

class Exception {

public:
   Exception(const string& msg,int val) : msg_(msg),e(val) {}
  ~Exception( ) {}

   string getMessage( ) const {return(msg_);}
   int what(){ return e;}
private:
   string msg_;
   int e;
};

现在基于 NULL 指针检查它可以像这样抛出, throw(Exception("NullPointerException",NULL));下面是捕获相同内容的代码。

 catch(Exception& e) {
      cout << "Not a valid object: " << e.getMessage( )<< ": ";

        cout<<"value="<<e.what()<< endl;
   }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top