温馨提示×

linux c++为什么段错误

小樊
42
2026-09-02 02:54:49
栏目: 编程语言

在 Linux 下用 C/C++ 编程时,**段错误(Segmentation fault,简称 segfault)**的本质原因是:

程序访问了它没有权限访问的内存地址
(或访问了“不存在”的内存)

操作系统(Linux 内核)通过 MMU(内存管理单元)检测到非法访问,于是给进程发送 SIGSEGV 信号,进程默认终止,就出现了段错误。


一、段错误的常见原因(最常见)

1. 空指针解引用(最多)

int* p = nullptr;
*p = 10;   // 段错误

或:

char* s = NULL;
strlen(s);

2. 使用已释放的内存(野指针)

int* p = new int(5);
delete p;
*p = 10;   // 段错误

3. 数组越界

int a[5];
a[10] = 1;   // 可能段错误

越界不一定立刻崩溃,但会破坏内存,后面莫名其妙 segfault


4. 栈溢出

void f() {
    f();   // 无限递归
}

或超大局部数组:

char buf[10 * 1024 * 1024]; // 可能栈溢出

5. 访问已销毁的对象

int& f() {
    int x = 10;
    return x;   // 返回局部变量引用
}

6. 多线程问题

  • 一个线程 delete 了对象
  • 另一个线程还在用

这是最难排查的段错误之一


7. 类型转换错误

Base* b = new Derived();
Other* o = (Other*)b;
o->func();   // 段错误

8. 已损坏的虚函数表

delete 错对象 / 内存被踩
obj->virtual_func(); // 段错误

二、Linux 下如何排查段错误

1️⃣ 用 gdb(最常用)

g++ -g main.cpp -o main
gdb ./main
run

段错误后:

bt      # 查看调用栈
frame 0
print 变量

2️⃣ 用 core dump(非常重要)

ulimit -c unlimited
./main

生成 core 文件后:

gdb ./main core
bt

3️⃣ AddressSanitizer(强烈推荐)

g++ -fsanitize=address -g main.cpp -o main
./main

能直接告诉你:

  • 哪一行越界
  • 哪块内存被释放后使用

4️⃣ strace(看系统调用)

strace ./main

5️⃣ dmesg(看内核日志)

dmesg | tail

三、简单总结一句话

Linux C++ 段错误 = 非法内存访问

最常见的就是:

  • 空指针
  • 野指针
  • 越界
  • 多线程乱用内存

如果你愿意,可以把:

  • 段错误代码
  • 或 gdb/asan 报错信息

贴出来,我可以帮你精确定位是哪一行导致的

0