1. 什么是段错误(Segmentation Fault)
段错误(Segmentation Fault,简称Segfault)是C/C++程序员最常遇到的运行时错误之一。当程序试图访问未被分配给它的内存区域,或者以错误方式访问已分配内存时,操作系统会触发保护机制,强制终止程序运行并报出Segmentation Fault错误。
在实际开发中,我遇到过无数由不同原因导致的段错误。有些错误很明显,比如解引用空指针;有些则很隐蔽,比如数组越界访问。理解段错误的本质,能帮助开发者快速定位和修复这类问题。
注意:段错误不是C语言标准的一部分,而是操作系统层面的保护机制。不同操作系统可能有不同的错误提示方式,比如Windows上常见的"访问冲突"(Access Violation)本质上也是类似的错误。
2. 段错误的常见原因分析
2.1 空指针解引用
这是最常见的段错误原因。当程序试图通过一个值为NULL的指针访问内存时,就会触发段错误。
c复制int *ptr = NULL;
*ptr = 10; // 这里会触发段错误
在实际项目中,空指针问题经常出现在以下几种场景:
- 忘记检查malloc/calloc的返回值
- 函数返回NULL但调用方未做检查
- 指针被意外赋值为NULL
2.2 数组越界访问
C语言不会自动检查数组边界,越界访问可能导致段错误。
c复制int arr[10];
arr[10] = 5; // 越界访问,可能触发段错误
更隐蔽的情况是负索引:
c复制int arr[10];
arr[-1] = 5; // 同样可能触发段错误
2.3 访问已释放的内存
使用free释放内存后,指针变成了"悬垂指针",继续访问会导致段错误。
c复制int *ptr = malloc(sizeof(int)*10);
free(ptr);
ptr[0] = 1; // 段错误
2.4 栈溢出
递归调用过深或局部变量占用空间过大,可能导致栈空间耗尽。
c复制void infinite_recursion() {
infinite_recursion(); // 最终会导致栈溢出
}
