C语言中字符串数组使用gets函数的输入异常问题排查
问题分析与解决
你的代码存在两个致命问题,直接导致了输入异常:
1. 未为单个字符串分配内存
你仅给字符串指针数组str分配了空间(malloc(sizeof(char*)*n)),但每个str[i]都是未初始化的野指针,指向的内存地址完全随机。直接用gets(str[i])往里面写数据会触发未定义行为——前两次输入可能侥幸成功,但很快就会破坏程序内存结构,导致后续输入无法正常进行,甚至直接崩溃。
2. gets函数已被废弃且不安全
gets不检查输入长度,极易造成缓冲区溢出;同时它会直接读取输入流中的换行符,虽然后你用%*c吃掉了scanf后的换行,这部分没问题,但gets本身的设计缺陷依然是隐患。
修复后的代码示例
#include <stdio.h> #include <stdlib.h> #include <string.h> // 你的自定义函数示例 void func(char **str, int n) { for (int i = 0; i < n; i++) { printf("第%d个字符串:%s\n", i+1, str[i]); } } int main() { int n, i; printf("Number of strings is: "); scanf("%d%*c", &n); // 分配指针数组内存 char **str = malloc(sizeof(char*) * n); if (str == NULL) { // 检查内存分配是否成功 perror("malloc failed"); return 1; } for (i = 0; i < n; i++) { printf("Input %d. string: ", i+1); // 为每个字符串分配内存,这里假设最大长度100,可按需调整 str[i] = malloc(100 * sizeof(char)); if (str[i] == NULL) { perror("malloc failed for string"); // 释放已分配的内存,避免泄漏 for (int j = 0; j < i; j++) { free(str[j]); } free(str); return 1; } // 用fgets替代gets,指定缓冲区大小避免溢出 fgets(str[i], 100, stdin); // 去掉fgets读取到的末尾换行符 str[i][strcspn(str[i], "\n")] = '\0'; } // 调用自定义函数处理字符串数组 func(str, n); // 释放所有内存,避免泄漏 for (i = 0; i < n; i++) { free(str[i]); } free(str); return 0; }
关键修复点说明
- 为每个
str[i]单独分配内存,确保有合法的存储空间存放输入字符串。 - 用
fgets替代gets,fgets可指定缓冲区大小,避免溢出;同时手动去除读取到的换行符(fgets会把输入时的回车也读入字符串)。 - 增加内存分配失败的检查逻辑,避免程序崩溃。
- 使用完内存后逐一释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者KeyboardSound
相关产品推荐
相关产品推荐

