K&R《C程序设计语言》习题13运行出现Segmentation Fault求助
段错误原因分析与修复方案
核心问题1:数组索引越界(直接触发段错误)
你定义histogram数组时用了int histogram[longestWord];,数组的有效索引范围是0到longestWord-1。但统计单词长度时,你用histogram[lengthArray[i]] += 1——lengthArray[i]是单词的实际长度,比如最长单词长度为5,那长度为5的单词会访问histogram[5],但此时数组只有5个元素(索引0-4),直接越界写入非法内存,触发段错误。
核心问题2:未初始化变量引发的异常
length变量未初始化为0,第一次遇到非空白字符时length++会基于随机内存值累加,可能让longestWord变成一个超大数值,导致histogram数组占用过多栈空间直接溢出,或者加剧索引越界问题。lastChar同样未初始化,第一次循环如果输入空白字符,判断lastChar != ' '会读取随机值,行为完全不可预测。
修复后的完整代码
#include <stdio.h> #include <termios.h> #include <unistd.h> #define ARRAY_SIZE 99 int main() { struct termios old_tio, new_tio; tcgetattr(STDIN_FILENO, &old_tio); new_tio = old_tio; new_tio.c_lflag &= (~ICANON & ~ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &new_tio); // 初始化所有变量,消除未定义行为 int c, length = 0, lengthArray[ARRAY_SIZE], word = 0, lastChar = ' ', longestWord = 0; while ((c = getchar()) != 'q') { if (c == ' ' || c == '\t' || c == '\n') { if (lastChar != ' ' && lastChar != '\t' && lastChar != '\n') { lengthArray[word] = length; word++; length = 0; } } else { length++; if (length > longestWord) longestWord = length; } putchar(c); lastChar = c; } // 数组大小改为longestWord + 1,容纳从0到longestWord的索引 int histogram[longestWord + 1]; for (int i = 0; i <= longestWord; i++) { histogram[i] = 0; } for (int i = 0; i < word; i++) { histogram[lengthArray[i]] += 1; } // 从1开始遍历,因为不存在长度为0的单词 for (int i = 1; i <= longestWord; i++) { printf("%d: %d\n", i, histogram[i]); } tcsetattr(STDIN_FILENO, TCSANOW, &old_tio); return 0; }
关键修复说明
- 给
length和lastChar赋初始值,避免未定义行为。 - 将
histogram数组的大小调整为longestWord + 1,确保能容纳所有可能的单词长度对应的索引。 - 调整最后打印循环的范围,从
i=1到i<=longestWord,跳过无意义的0长度统计。
内容的提问来源于stack exchange,提问作者Jonas1_4
相关产品推荐
相关产品推荐

