使用getline()读取stdin并存储到字符串数组时出现内容覆盖问题求助
问题分析与修正
你的代码存在两个核心问题,导致之前的输入被覆盖:
1. 指针数组内存分配错误
主函数中malloc的写法完全错误:
char ** inputList = (char**)malloc( sizeof(char) * 100 * 100 );
inputList是指向char指针的指针(即字符串数组),需要为每个字符串指针分配空间,而非直接分配char类型的内存块。原写法会让inputList的所有元素指向连续的同一块char内存,后续getline写入时会直接覆盖之前的内容。
2. getline的size参数使用错误
getline的第二个参数是传入输出型指针,用于告知当前缓冲区大小,同时getline会根据输入长度重新分配内存并更新该值。你当前以值传递方式传入固定size,且未让scanItem修改主函数的size变量,导致getline无法正确管理独立缓冲区,重复使用同一块内存。
修正后的完整代码
修正后的scanItem函数
#include <stdio.h> #include <stdlib.h> int scanItem(char **list, size_t *size) { // getline返回ssize_t,区分成功/失败 ssize_t res = getline(list, size, stdin); // 检查读取成功,且输入长度符合要求(res包含换行符) if (res != -1 && res > 5 && res < 100) { // 可选:移除末尾换行符 if ((*list)[res - 1] == '\n') { (*list)[res - 1] = '\0'; } return 1; } return 0; }
修正后的主函数
int main(void) { // 分配能存储100个字符串指针的数组 char **inputList = malloc(sizeof(char*) * 100); if (inputList == NULL) { perror("malloc failed"); return EXIT_FAILURE; } size_t size = 0; // 初始化为0,让getline自动分配内存 int i = 0; // 限制数组下标,防止越界 while (i < 100 && scanItem(&inputList[i], &size) == 1) { size = 0; // 重置size,确保下一次getline分配独立缓冲区 i++; } if (!feof(stdin)) { // 这里补充你的error()实现 fprintf(stderr, "Input error or line out of range\n"); } // 释放内存,避免泄漏 for (int j = 0; j < i; j++) { free(inputList[j]); } free(inputList); return EXIT_SUCCESS; }
关键修改说明
- 指针数组分配:
malloc(sizeof(char*) * 100)为每个字符串指针单独分配地址空间,确保每个输入行存储在独立缓冲区。 - size参数改为指针传递:让
getline能修改主函数中的size变量,正确处理内存分配与扩容。 - 初始化size为0:
getline会自动分配足够内存存储输入,无需预先分配大缓冲区。 - 循环重置size:每次读取新行前重置size,强制
getline为新输入分配全新内存,避免复用之前的缓冲区。 - 内存释放:使用完后必须逐个释放
getline分配的字符串,再释放指针数组,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Nox5692
相关产品推荐
相关产品推荐

