我试图使一个Python程序接口与不同的崩溃进程(这是我的手)。不幸的是,我正在使用的程序甚至不会可靠地崩溃!所以我想做一个快速的c++程序,它会故意崩溃,但我不知道最好和最短的方法来做到这一点,有人知道在我的

int main() {
    crashyCodeGoesHere();
}

使我的c++程序可靠地崩溃


当前回答

我唯一的闪光是abort()函数:

它以异常的程序终止终止进程。它生成SIGABRT信号,默认情况下,该信号导致程序终止,并向主机环境返回一个不成功的终止错误代码。程序终止时不执行自动或静态存储持续时间对象的析构函数,也不调用任何atexit(在程序终止前由exit()调用)函数。它从不返回调用者。

其他回答

由于崩溃是调用未定义行为的症状,并且由于调用未定义行为可能导致任何事情,包括崩溃,我认为您不希望真正使程序崩溃,而只是将它放入调试器中。最可移植的方法可能是abort()。

虽然raise(SIGABRT)具有相同的效果,但它肯定更适合编写。然而,这两种方式都可以通过为SIGABRT安装信号处理程序来拦截。因此,根据您的情况,您可能想要/需要发出另一个信号。SIGFPE, SIGILL, SIGINT, SIGTERM或SIGSEGV可能是可行的方法,但它们都可以被拦截。

当您无法移植时,您的选择可能更广泛,比如在linux上使用SIGBUS。

我看到这里张贴了许多答案,它们将成为完成工作的幸运案例,但没有一个是100%确定崩溃的。一些会在一个硬件和操作系统上崩溃,另一些不会。 然而,根据官方c++标准,有一种标准方法可以使它崩溃。

引用c++标准ISO/IEC 14882§15.1-7:

If the exception handling mechanism, after completing the initialization of the exception object but before the activation of a handler for the exception, calls a function that exits via an exception, std::terminate is called (15.5.1). struct C { C() { } C(const C&) { if (std::uncaught_exceptions()) { throw 0; // throw during copy to handler’s exception-declaration object (15.3) } } }; int main() { try { throw C(); // calls std::terminate() if construction of the handler’s // exception-declaration object is not elided (12.8) } catch(C) { } }

我写了一个小代码来演示这一点,可以在这里找到并在Ideone上试用。

class MyClass{
    public:
    ~MyClass() throw(int) { throw 0;}
};

int main() {
  try {
    MyClass myobj; // its destructor will cause an exception

    // This is another exception along with exception due to destructor of myobj and will cause app to terminate
     throw 1;      // It could be some function call which can result in exception.
  }
  catch(...)
  {
    std::cout<<"Exception catched"<<endl;
  }
  return 0;
}

ISO/IEC 14882§15.1/9提到throw没有try块导致隐式调用abort:

如果当前没有处理异常,则执行 没有操作数的抛出表达式调用std::terminate()

其他包括: throw from析构函数:ISO/IEC 14882§15.2/3

 throw 42;

只要回答……:)

这会在我的Linux系统上崩溃,因为字符串文字存储在只读内存中:

0[""]--;

顺便说一下,g++拒绝编译这个。编译器变得越来越聪明:)

int i = 1 / 0;

您的编译器可能会警告您这一点,但在GCC 4.4.3下它编译得很好 这可能会导致SIGFPE(浮点异常),这在实际应用程序中可能不像SIGSEGV(内存分段违反)那样可能导致其他答案,但它仍然是崩溃。在我看来,这样可读性更强。

另一种方法,如果我们要欺骗和使用signal.h,是:

#include <signal.h>
int main() {
    raise(SIGKILL);
}

这保证杀死子进程,与SIGSEGV形成对比。