温馨提示×

ubuntu c++为何报段错误

小樊
43
2026-10-05 08:34:09
栏目: 编程语言

在 Ubuntu 下用 C++ 写程序出现段错误(Segmentation fault,SIGSEGV),本质原因只有一个:

程序访问了它不该访问的内存地址

下面按「常见原因 → 排查方法 → 示例」给你系统讲一下。


一、段错误的常见原因(90% 都在这)

1️⃣ 空指针解引用(最常见)

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

或:

MyClass* obj = nullptr;
obj->foo();

2️⃣ 数组越界 / 野指针

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

或:

int* p = new int[5];
delete[] p;
p[0] = 1;   // 已释放,野指针

3️⃣ 使用已释放的内存

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

4️⃣ 栈溢出

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

或超大局部变量:

char buf[1024 * 1024 * 100]; // 栈爆了

5️⃣ 多线程问题

  • 一个线程 delete 了对象
  • 另一个线程还在用
// 线程A
delete ptr;

// 线程B
ptr->do();   // 段错误

6️⃣ main 返回前对象已析构

A& get() {
    A a;
    return a;  // 返回局部变量引用
}

7️⃣ 第三方库 / 系统调用参数错误

  • 给 write()、recv() 传了错误指针
  • 动态库版本不匹配

二、如何快速定位段错误(Ubuntu 必学)

✅ 方法 1:用 gdb(最推荐)

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

进入 gdb 后:

run
bt

bt(backtrace)会直接告诉你在哪一行崩溃。


✅ 方法 2:core dump

ulimit -c unlimited
./main

生成 core 文件后:

gdb ./main core
bt

✅ 方法 3:AddressSanitizer(强烈推荐)

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

它会精确告诉你:

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

✅ 方法 4:加日志(简单但慢)

cout << "before func" << endl;
func();
cout << "after func" << endl;

三、一个典型段错误示例

#include <iostream>
using namespace std;

int main() {
    int* p = nullptr;
    cout << *p;   // 段错误
}

编译运行:

g++ test.cpp
./a.out
Segmentation fault (core dumped)

四、总结一句话

段错误不是 Ubuntu 的问题,而是你的程序踩了内存红线

如果你愿意,可以把:

  • 报错代码
  • 或 gdb 的 bt 输出

贴出来,我可以直接帮你定位是哪一行、为什么崩。

0 踩