C语言字符串反转程序触发Segmentation fault段错误的解决方法
问题原因与解决方案
核心错误点
- 第一个致命错误:
char *word是未初始化的野指针,scanf("%s", word)直接向随机内存地址写入输入的字符串,属于非法内存访问,输入内容长度只要超出该随机地址可写的内存范围就会触发段错误,你之前短字符串没崩溃纯属运气。 - 第二个错误:
malloc(len)申请的内存大小缺少1字节用于存储字符串末尾的终止符\0,strcpy执行时会将word末尾的\0写入str申请内存的边界之外,同样属于越界访问。 - 额外隐患:直接用
scanf("%s", 指针)无法限制写入长度,也不支持动态适配任意长度的输入。
修复后的完整代码
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { int i, len = 0, capacity = 16; // 初始容量设为16,输入长度不够时自动扩容 char *word = (char *)malloc(capacity); char *str, cp; int ch; if (word == NULL) { perror("malloc failed"); return 1; } printf("Input An English word > "); // 动态读取输入,直到遇到空格/换行/EOF,适配任意长度输入 while ((ch = getchar()) != EOF && ch != ' ' && ch != '\n') { if (len + 1 >= capacity) { // 预留1字节存储字符串终止符 capacity *= 2; char *temp = (char *)realloc(word, capacity); if (temp == NULL) { perror("realloc failed"); free(word); return 1; } word = temp; } word[len++] = ch; } word[len] = '\0'; // 手动添加字符串终止符 printf("%d\n", len); str = (char *)malloc(len + 1); // 多申请1字节存储字符串终止符 if (str == NULL) { perror("malloc failed"); free(word); return 1; } strcpy(str, word); for(i=0; i < (len/2); i++) { cp = str[i]; str[i] = str[len - i - 1]; str[len - i - 1] = cp; } printf("%s\n", str); // 释放动态内存避免泄漏 free(word); free(str); return 0; }
修复说明
- 替换了直接用
scanf读入到野指针的逻辑,改为预先申请小容量动态内存,输入字符超过当前容量时自动扩容,完全适配任意长度的输入,符合需求中不需要预先知道单词长度、不使用变长数组的要求。 - 所有动态内存申请都增加了失败校验,避免空指针访问。
- 修正了
malloc的申请长度,预留了字符串终止符的存储空间。 - 最后增加了动态内存释放逻辑,避免内存泄漏。
内容的提问来源于stack exchange,提问作者ciganaiuecstd
相关产品推荐
相关产品推荐

