C语言将getline()结果存入外部数组后内容为空的问题
问题原因
你的代码存在两个核心错误导致读取到的行内容为空:
- 缓冲区复用问题:
getline()函数如果传入的行指针不为NULL,会直接复用该指针指向的已有缓冲区存储新行内容,不会重新分配内存。你每次循环仅将缓冲区地址赋值给srclns[count++],没有重置lnptr为NULL,导致所有srclns数组中的指针都指向同一块内存地址,后续每次读取新行都会覆盖之前存储的内容。 - 提前释放内存:循环结束后你直接调用
free(lnptr)释放了这块所有srclns指针共同指向的内存,导致srclns中存储的全是野指针,访问野指针属于未定义行为,你遇到的输出空字符串就是该行为的表现之一。
另外还存在隐含的数组越界风险:未判断读取行数超过MAXSRC的情况,读取行数超过20时会出现越界写入。
修复方案
- 每次将
lnptr赋值给srclns后,立刻将lnptr重置为NULL,让下一次getline调用自动分配新的缓冲区存储新行,避免复用同一块内存。 - 仅释放循环结束后未被存入
srclns的冗余缓冲区,不要释放已经存入数组的内存,使用完行内容后遍历srclns逐个释放即可。 - 补充数组越界检查,避免读取行数超过上限时的越界问题。
修正后代码
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #define MAXSRC 20 char *srclns[MAXSRC]; /* source lines */ size_t read_lines(char *path) { FILE *stream; ssize_t read; char *lnptr; size_t n; size_t count; stream = fopen(path, "r"); lnptr = NULL; n = 0; count = 0; if (!stream) { fprintf(stderr, "Can't open source '%s'\n", path); exit(EXIT_FAILURE); } while ((read = getline(&lnptr, &n, stream)) != -1) { // 数组越界检查 if (count >= MAXSRC) { free(lnptr); break; } srclns[count++] = lnptr; lnptr = NULL; // 重置为NULL,下次getline会自动分配新内存 } // 仅释放未存入数组的冗余缓冲区 free(lnptr); fclose(stream); return count; } int main() { size_t n = read_lines("foo.txt"); for (size_t i = 0; i < n; i++) { printf("%zu %s\n", i, srclns[i]); free(srclns[i]); // 用完后释放对应行的内存,避免泄漏 } exit(EXIT_SUCCESS); }
内容的提问来源于stack exchange,提问作者user12421304
相关产品推荐
相关产品推荐

