什么是C++中的SIGSEGV运行时错误?

Vai*_*hav 33 segmentation-fault

我需要知道分段错误的根本原因,也可以告诉我如何处理它.

Chr*_*utz 51

维基百科有答案,还有许多其他来源.

段错误基本上意味着你用指针做了坏事.这可能是一个段错误:

char *c = NULL;
...
*c; // dereferencing a NULL pointer
Run Code Online (Sandbox Code Playgroud)

或这个:

char *c = "Hello";
...
c[10] = 'z'; // out of bounds, or in this case, writing into read-only memory
Run Code Online (Sandbox Code Playgroud)

或许这个:

char *c = new char[10];
...
delete [] c;
...
c[2] = 'z'; // accessing freed memory
Run Code Online (Sandbox Code Playgroud)

在每种情况下都有相同的基本原则 - 你正在做一些不属于你的记忆.


Jon*_*ler 12

分段错误有多种原因,但从根本上说,您正在错误地访问内存.这可能是由于解除引用空指针,或者尝试修改只读内存,或者使用指向未映射到进程内存空间的某个地方(这可能意味着您尝试使用数字作为指针) ,或者你将指针递增太多).在某些机器上,通过指针进行错位访问也可能导致问题 - 例如,如果您有一个奇数地址并尝试从中读取偶数个字节(例如,可以生成SIGBUS).


小智 10

SigSegV 表示内存访问冲突的信号,尝试从进程无权访问的内存区域读取或写入。这些不是 C 或 C++ 异常,您可以\xe2\x80\x99t 捕获信号。确实可以编写一个信号处理程序来忽略问题并允许在未定义状态下继续执行不稳定的程序,但很明显这是一个非常糟糕的主意。

\n\n

大多数时候这是因为程序中的错误。给出的内存地址可以帮助调试问题是什么(如果它接近于零,那么它可能是空指针取消引用,如果地址类似于 0xadcedfe 那么it\xe2\x80\x99s有意保护或调试检查等)

\n\n

\xe2\x80\x9c 捕获\xe2\x80\x9d 信号的一种方法是在一个单独的子进程中运行你的东西,然后该子进程可以突然终止,而不会导致你的主进程随之关闭。找到根本原因并解决它显然比这样的解决方法更可取。

\n


Mic*_*elM 6

使用无效/空指针?超越数组的界限?没有任何示例代码,很难确定Kindof。

本质上,您试图访问不属于您的程序的内存,因此操作系统会杀死它。


pie*_*fou 6

这是 SIGSEGV 的示例。

root@pierr-desktop:/opt/playGround# cat test.c
int main()
{
     int * p ;
     * p = 0x1234;
     return 0 ;
}
root@pierr-desktop:/opt/playGround# g++ -o test test.c  
root@pierr-desktop:/opt/playGround# ./test 
Segmentation fault
Run Code Online (Sandbox Code Playgroud)

这是细节

如何处理?

  1. 首先尽可能避免它。

    防御性编程:使用 assert(),检查 NULL 指针,检查缓冲区溢出。

    使用静态分析工具检查您的代码。

    使用 -Werror -Wall 编译您的代码。

    有人审查您的代码。

  2. 当那真的发生了。

    仔细检查你的代码。

    检查自上次代码成功运行而没有崩溃以来所做的更改。

    希望 gdb 会给您一个调用堆栈,以便您知道崩溃发生的位置。


编辑:抱歉匆忙。它应该*p = 0x1234;代替 p = 0x1234;

  • 该程序无法使用任何 C++ 编译器进行编译。如果添加必要的转换,它就不会崩溃,因为它实际上没有任何无效的内存访问。 (2认同)