C语言使用变量i访问字符串数组触发Segmentation Fault问题
问题根因
- 第一处错误是数组下标越界:你遍历
notes数组匹配输入音符的for循环,终止条件是i < 12,当循环完整执行结束后,循环变量i的值会自增到12。但notes是长度为12的数组,合法下标范围是0~11,下标12已经超出数组的内存边界,访问notes[12]属于非法内存访问。 - 第二处错误是变量作用域误用:你在if判断的代码块内部定义了
int notePosition = i,这个变量是if块的局部变量,一旦出了if的大括号就会被销毁,外部代码根本拿不到匹配到的下标值,这也是你最后错误选择用循环结束后的i访问数组的直接原因。 - 你在gdb中看到的
0x47地址,本质是字符'G'的ASCII码值(十进制71对应十六进制0x47)。越界访问拿到的值根本不是一个合法的字符串指针,printf尝试把这个值当作内存地址去读字符串,直接访问到了受系统保护的低地址内存,就触发了段错误。 - 额外的小问题:你写的
else;是无效空语句,不会执行任何逻辑,虽然不直接触发报错,但属于冗余代码。
修复方案
- 把存储音符下标的
notePosition变量定义到for循环的外部,初始值设为-1,用来标记「未找到匹配音符」的状态。 - 匹配到音符时,直接给外部定义的
notePosition赋值,不要在if块内重新定义同名局部变量;匹配成功后可以直接用break跳出循环,不需要继续遍历剩余元素。 - 循环结束后先校验
notePosition的值,确认找到合法下标后,再用notePosition作为下标访问notes数组,不要用循环跑完后已经越界的i。 - 增加非法输入判断:如果
notePosition还是初始值-1,提示用户输入的音符不在合法列表里。
修复后的核心逻辑代码如下:
int notePosition = -1; // 循环外定义存储位置的变量 for (i = 0; i < 12; ++i) { if (strcmp(pickedNote, notes[i]) == 0) { notePosition = i; printf("Your note is in position %d\n", notePosition); break; // 找到即终止循环 } } // 校验下标合法性后再访问数组 if (notePosition != -1) { printf("%s\n", notes[notePosition]); } else { printf("输入的音符不在可选范围内\n"); }
内容的提问来源于stack exchange,提问作者Rudy F.
相关产品推荐
相关产品推荐

