为什么我不能导致段故障?

时间:2010-01-11 22:07:39

标签: c++ segmentation-fault

无论出于何种原因我都遇到了导致seg故障的问题。我想制作一个,以便我可以使用gdb来查看如何调试一个。我试过the Wikipedia文章中的两个例子,但都没有用。

第一个:

char *s = "Hello World!";
*s = 'H';

第二个例子:

int main(void) 
{
    main();
}

编辑:我正在使用Ubutnu 9.10和g++作为我的编译器。任何人都可以向我展示一些保证会出现段错误的代码吗?

10 个答案:

答案 0 :(得分:39)

尝试和可靠地取消引用指针是不可能的 这是因为应用程序处理内存的方式因编译器和编译器而异,也可能在具有不同选项的同一编译器之间(调试/发布模式不同)。

您可以做的是使用信号显式提升段错误:

#include <signal.h>

int main()
{
    raise(SIGSEGV);
}

答案 1 :(得分:18)

我的一线风味:

*(char *)0 = 0;

答案 2 :(得分:6)

有史以来最短的段错误:

*(int*)0=0;

答案 3 :(得分:5)

你做的两件事都会在C ++中产生“未定义的行为”(好吧,实际上是禁止调用main())。不能保证它们会导致seg错误 - 这将取决于很多事情,但主要是你正在运行的平台,你没有指定。

事实上,任何建议的导致seg故障的方法可能会也可能不会起作用。这是因为seg错误几乎总是与C ++的未定义行为概念相关联。

答案 4 :(得分:2)

int *hello = NULL;
printf(*hello);

或者你可以定义一个结构(比如HelloWorld struct)

HelloWorld *myWorld = NULL;
myWorld->world = "hello";

答案 5 :(得分:2)

对于第一个例子,编译器可能将字符串放在可写内存中,因此在尝试更改时没有seg错误。

对于第二种情况,编译器可能正在优化调用,或者可能正在优化调用本身而只是跳转(因为它是tail call),这意味着堆栈实际上并没有增加返回地址对于每次通话,所以你可以无限期地递减。

但是正如Neil在他的帖子中提到的,任何这些都会导致“未定义的行为”,因此在运行时不需要代码来生成seg错误。

答案 6 :(得分:1)

char * ptr = 0;
*ptr = 1;

Segmentation fault

答案 7 :(得分:1)

产生段错误的方法很多。

喜欢解除引用错误的指针:

char *s = (char *)0xDEADBEEF;
*s = 'a';

答案 8 :(得分:1)

维基百科的文章实际上列出了三种方法(其中一种是空指针取消引用);你为什么不尝试那个?

至于为什么你试过的两个例子没有,正如其他人所指出的那样正确的答案是它是未定义的行为,所以任何事情都可能发生(包括不包括segfaulting)。但是可以推测,第一种形式没有失败的原因是因为你的编译器或系统对内存保护不严。至于第二种情况,可以想象一种尾递归感知编译器可以优化无限递归main循环,而不会最终溢出堆栈。

答案 9 :(得分:1)

如果你尝试连接两个常量......你会得到一个...至少是一个简单的方法......

strcat(“a”,“b”);

=)