C语言替换密码程序报段错误 如何正确向main函数返回字符串
问题描述
程序实现目标为替换加密:将明文字符串中的字符替换为对应密文字符,用户需通过命令行参数输入26个字母作为加密密钥。
运行程序时抛出Segmentation fault (core dumped)报错,调试发现代码运行至密钥处理函数时停止工作,需要定位故障原因,修复后正确生成密钥字符串返回main函数,完成加密流程。
故障原因
段错误由非法内存写入直接触发,核心问题有3个:
valid_key_upper函数内定义string key_upper = NULL;,cs50头文件中string本质是char*字符指针类型,这里仅将指针初始化为空,没有为其分配可写入的实际内存空间,后续直接执行key_upper[i] = key[i]、key_upper[26] = '\0'的赋值操作,本质是向内存地址0的受保护区域写数据,直接触发段错误。- 内存长度预留不足:main函数中定义的原始密钥数组
char key[26]仅分配了26字节,C语言字符串需要额外1字节存储结束符\0,即使指针问题修复,后续写入结束符时也会触发栈内存越界。 - 附带逻辑bug:密钥去重循环的起始下标为1,永远不会校验第一个存入的密钥字符,会漏判第一个字符与后续字符重复的场景;且去重时未做大小写统一,同一个字母的大小写形式会被误判为不重复。
修复方案
- 为密钥字符串分配足够的可写内存:密钥处理函数中不要直接使用空指针赋值,可以用长度27的静态字符数组存储转换后的密钥(26个字母+1个结束符),也可以在main函数中预分配27字节的数组传入函数修改。
- 修正去重逻辑:循环从下标0开始遍历已存储的密钥字符,比对时统一转大写或小写,避免漏判重复。
- 原始密钥数组长度改为27字节,预留结束符位置。
核心修复代码
// 修复后的大写密钥转换函数,小写密钥转换函数逻辑一致 string valid_key_upper(string key) { // 静态数组分配27字节空间,函数退出后内存不会被回收,可正常返回给main使用 static char key_upper[27]; for (int i = 0; i < 26; i++) { key_upper[i] = toupper(key[i]); } key_upper[26] = '\0'; return key_upper; } // main函数中密钥校验部分修正 int main(int argc, string argv[]) { // ... 省略原有参数数量、长度校验逻辑 ... // 原始密钥数组长度改为27,预留结束符位置 char key[27]; int evaluated_key = 0; for (int i = 0; i < key_length; i++) { // 直接用ctype库的isalpha函数判断是否为字母,比硬编码ASCII码可读性更强 if (!isalpha(key_before[i])) { printf("Must only contain letters!\n"); return 1; } else { // 从下标0开始遍历已存密钥,统一转大写后比对去重 for (int n = 0; n < evaluated_key; n++) { if (toupper(key_before[i]) == toupper(key[n])) { printf("Must not contain duplicate!\n"); return 1; } } key[i] = key_before[i]; evaluated_key++; } } key[26] = '\0'; // 给原始密钥补结束符 // ... 省略后续逻辑 ... }
提示:如果使用
malloc(27)动态分配内存存储密钥,需要在程序退出前调用free释放对应内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者armandotop122
相关产品推荐
相关产品推荐

