CS50 Caesar Cypher程序编译成功后出现segmentation fault,求原因排查
段错误根因分析
- 第一个触发点:密钥校验逻辑下标使用错误
代码中for (int j = 0; j <= strlen(argv[1]); j++)循环内的判断写为isdigit(argv[j]),argv是命令行参数数组,当argc=2时有效下标只有0和1,j增长到1以上时,argv[j]属于参数数组的越界访问区域,直接触发段错误。正确写法应为isdigit(argv[1][j]),遍历argv[1]指向的密钥字符串的每个字符。另外循环条件j <= strlen(argv[1])会遍历到字符串终止符\0,属于逻辑错误但不会直接触发段错误。 - 第二个触发点:空指针直接写操作
代码中string cypher = NULL;定义后没有分配内存,就直接执行cypher[i] = xxx的写操作,相当于往NULL地址偏移i位的非法内存位置写入数据,必然触发段错误。需要先给cypher分配足够的内存,比如string cypher = malloc(s + 1);,分配和明文长度匹配的空间+1位存储字符串终止符,分配后还要检查是否为NULL避免分配失败。
(额外逻辑说明:处理明文的循环中else分支写了i++,和for循环自带的i++叠加会导致每隔一个字符处理一次,属于逻辑错误但不触发段错误)
段错误排查常用技巧
- 编译时开启调试信息:编译指令加
-g参数,使用gdb调试运行崩溃程序,执行bt命令即可直接定位到触发崩溃的代码行 - 启用地址消毒工具:编译时加
-fsanitize=address参数,运行程序时会直接输出非法内存访问的类型、具体代码位置、访问的内存属性(比如是否是空指针访问、是否是堆/栈越界),排查效率极高 - 指针访问前先判空:所有指针操作前增加非空判断,避免空指针访问
- 核对遍历边界:所有数组、字符串遍历前确认有效下标范围,避免越界访问
内容的提问来源于stack exchange,提问作者Potential_Lettuce
相关产品推荐
相关产品推荐

