Windows VSCode正常运行的Caesar cipher代码在Ubuntu VSCode中出现Segmentation fault
段错误原因及修复方案
你的代码在Linux下触发段错,核心原因是非法内存访问和内存分配未符合字符串规范,以下是具体问题及修复:
1. 野指针导致非法内存写入
- 问题:
main函数中char *input;仅声明指针但未初始化,属于野指针(指向随机内存地址)。gets(input)会向这块随机内存写入数据,属于未定义行为——Windows环境可能因内存布局侥幸未触发错误,但Linux内存管理更严格,直接触发段错误。另外gets函数已被C标准废弃,存在严重缓冲区溢出风险。 - 修复:改用栈数组或提前分配内存,同时替换
gets为安全的fgets:// 示例:使用栈数组,指定足够大小 char input[256]; printf("Enter the text to be encrypted : "); fgets(input, sizeof(input), stdin); // 去掉fgets读取的换行符 input[strcspn(input, "\n")] = '\0';
2. 内存分配未预留字符串终止符空间
- 问题:
Encrypted函数中malloc(length)仅分配了等于输入长度的内存,但C字符串需要末尾的'\0'标记结束。后续strcpy、strncat会越界写入,破坏堆内存结构,引发段错误。 - 修复:分配内存时多留1字节给终止符:
char * encrypt = malloc(length + 1);
3. 低效且存在风险的字符串拼接
- 问题:用
strncat逐个字符拼接效率极低,且依赖encrypt初始化为空字符串。strcpy(encrypt, "")虽能初始化,但直接操作下标更高效安全。 - 修复:直接通过下标赋值字符,最后手动添加终止符:
char * encrypt = malloc(length + 1); for(int i=0; i < length; i++){ int current = (int)curr[i]; // 仅处理大写字母,其他字符直接保留 if (current >= 'A' && current <= 'Z') { encrypt[i] = (char)('A' + (current + key - 'A') % 26); // 处理负数取模的情况(比如key为负时) if (encrypt[i] < 'A') encrypt[i] += 26; } else { encrypt[i] = current; } } encrypt[length] = '\0'; // 手动添加终止符
修复后的完整代码
#include<stdio.h> #include<string.h> #include<stdlib.h> char * Encrypted(char ** input, int key){ int length = strlen(*input); char * curr = *input; char * encrypt = malloc(length + 1); if (encrypt == NULL) { // 检查malloc是否成功 perror("malloc failed"); exit(EXIT_FAILURE); } for(int i=0; i < length; i++){ int current = (int)curr[i]; if (current >= 'A' && current <= 'Z') { int offset = (current + key - 'A') % 26; encrypt[i] = (char)('A' + (offset < 0 ? offset + 26 : offset)); } else { encrypt[i] = current; } } encrypt[length] = '\0'; return encrypt; } int main(void){ char input[256]; printf("Enter the text to be encrypted : "); fgets(input, sizeof(input), stdin); input[strcspn(input, "\n")] = '\0'; // 移除换行符 int key; printf("Enter the key : "); scanf("%d", &key); char *result = Encrypted(&input, key); printf("The encrypted text is : %s\n", result); free(result); // 释放malloc分配的内存,避免内存泄漏 return 0; }
内容的提问来源于stack exchange,提问作者Valiveti Swamy Naga Sai Nivas
相关产品推荐
相关产品推荐

