在 Linux 下用 C/C++ 编程时,**段错误(Segmentation fault,简称 segfault)**的本质原因是:
程序访问了它没有权限访问的内存地址
(或访问了“不存在”的内存)
操作系统(Linux 内核)通过 MMU(内存管理单元)检测到非法访问,于是给进程发送 SIGSEGV 信号,进程默认终止,就出现了段错误。
int* p = nullptr;
*p = 10; // 段错误
或:
char* s = NULL;
strlen(s);
int* p = new int(5);
delete p;
*p = 10; // 段错误
int a[5];
a[10] = 1; // 可能段错误
越界不一定立刻崩溃,但会破坏内存,后面莫名其妙 segfault
void f() {
f(); // 无限递归
}
或超大局部数组:
char buf[10 * 1024 * 1024]; // 可能栈溢出
int& f() {
int x = 10;
return x; // 返回局部变量引用
}
delete 了对象这是最难排查的段错误之一
Base* b = new Derived();
Other* o = (Other*)b;
o->func(); // 段错误
delete 错对象 / 内存被踩
obj->virtual_func(); // 段错误
g++ -g main.cpp -o main
gdb ./main
run
段错误后:
bt # 查看调用栈
frame 0
print 变量
ulimit -c unlimited
./main
生成 core 文件后:
gdb ./main core
bt
g++ -fsanitize=address -g main.cpp -o main
./main
能直接告诉你:
strace ./main
dmesg | tail
Linux C++ 段错误 = 非法内存访问
最常见的就是:
如果你愿意,可以把:
贴出来,我可以帮你精确定位是哪一行导致的。