什么是segmentation fault (core dumped)?K&R习题代码报该错如何修复
什么是segmentation fault (core dumped)
段错误(segmentation fault)是操作系统发出的内存访问错误信号,触发时会强制终止异常进程,本质是程序试图访问未分配给自己的内存、或访问没有读写权限的内存区域。后缀core dumped表示程序终止时将内存快照(core文件)写入磁盘,可用于后续调试定位问题。
常见成因及修复方法
- 访问未初始化的指针:指针未赋值就直接解引用,修复方案是定义指针时就初始化为合法地址或者
NULL,使用前先判空。 - 数组越界:读写数组时下标超出了数组定义的长度范围,修复方案是严格校验下标取值,确保下标始终落在
[0, 数组长度-1]范围内。 - 访问已释放的堆内存:堆内存调用
free释放后仍继续读写,修复方案是free后立刻将对应指针置为NULL,避免野指针访问。 - 修改只读内存:比如直接修改字符串常量的内容,修复方案是将需要修改的内容存储在栈、堆等可写内存区域。
- 栈溢出:递归调用层数过多、或者局部变量体积过大超过栈空间上限,修复方案是减少递归深度,大体积数组改用
malloc在堆上分配。
你提供的代码问题排查
你这段代码触发段错误的核心原因有以下几点:
- 变量
i未初始化就作为数组下标使用:你定义int c, i, j;后从未给i赋值,i的初始值是内存里的随机垃圾值,直接用line[i]赋值相当于随机写非法内存,直接触发段错误。 - 下标
i未更新:不管是写入普通字符还是替换tab为空格,操作完成后都没有修改i的值,下一个字符仍会写入旧下标位置,不仅逻辑错误,后续累积也会越界。 - tab替换逻辑错误:循环条件
j<TAB+1会插入5个空格,不符合TAB宽度为4的预期,应该改为j<TAB。 - 字符串无结束符:
line数组从未写入字符串结束符\0,调用printf("%s", line)时会一直向后读内存直到遇到随机的\0,触发越界访问。 - 无数组边界校验:没有判断
i是否超过MAXLINE,输入行过长时会直接越界。
修复后参考代码
#include <stdio.h> #define MAXLINE 1000 #define TAB 4 int main() { int c, i = 0, j; char line[MAXLINE]; while ((c = getchar()) != EOF && i < MAXLINE - 1) { if (c == '\n') { line[i] = '\0'; printf("%s\n", line); i = 0; // 换行后重置下标,处理下一行 } else if (c == '\t') { // 替换tab为对应数量空格 for (j = 0; j < TAB && i < MAXLINE - 1; j++) { line[i++] = ' '; } } else { line[i++] = c; } } // 处理最后一行没有换行的情况 if (i > 0) { line[i] = '\0'; printf("%s", line); } return 0; }
内容的提问来源于stack exchange,提问作者Lutpoint
相关产品推荐
相关产品推荐

