程序触发Segmentation fault(core dumped),疑与argv参数相关
问题分析与修复方案
触发段错误的核心原因
- 命令行参数索引错误:
argv数组中,argv[0]是程序自身的名称,你传入的26位密码应该对应argv[1],而非argv[2]。如果运行程序时仅传入一个密码参数,argv[2]会是NULL,对NULL调用strlen()直接触发段错误。 - 缺失参数数量校验:在访问
argv[1]之前,没有先检查argc是否等于2(程序名+密码参数)。如果用户未传入任何参数就运行程序,argv[1]为NULL,同样会引发段错误。
关键修复代码
1. 修正主函数的参数检查逻辑
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> // 新增malloc所需头文件 string replace(string word, string cipher); int main(int argc, string argv[]) { // 先校验参数数量是否正确 if (argc != 2) { printf("Usage: ./your_program_name [26-character cipher]\n"); return 1; } // 再检查密码长度是否符合要求 if (strlen(argv[1]) != 26) { printf("The cipher must be 26 characters\n"); return 1; } string plaintext = get_string("Plaintext: "); string result = replace(plaintext, argv[1]); // 用完后释放内存,避免内存泄漏 free(result); return 0; }
2. 修复replace函数的实现问题
原函数存在声明与定义不匹配、未分配内存就直接赋值、返回值错误等问题,修复后:
string replace(string word, string cipher) { // 为加密结果分配足够内存,+1用于存储字符串结束符'\0' string coded = malloc(strlen(word) + 1); if (coded == NULL) { printf("Memory allocation failed\n"); return NULL; } for (int i = 0; i < strlen(word); i++) { if (isalpha(word[i])) { int is_upper = isupper(word[i]); int n = tolower(word[i]) - 'a'; // 用字符常量替代魔数,提升可读性 // 保留原字符的大小写 coded[i] = is_upper ? toupper(cipher[n]) : cipher[n]; } else { // 非字母字符直接保留 coded[i] = word[i]; } } coded[strlen(word)] = '\0'; // 必须添加字符串结束符 printf("coded: %s\n", coded); return coded; }
额外说明
- 新增
<stdlib.h>头文件用于malloc和free函数。 - 使用
'a'替代魔数97,代码可读性更强且跨平台兼容。 - 内存分配后必须检查是否成功,避免后续操作
NULL指针。 - 字符串操作必须确保以
'\0'结尾,否则会出现未定义行为。
内容的提问来源于stack exchange,提问作者user21380365
相关产品推荐
相关产品推荐

