You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言将getline()结果存入外部数组后内容为空的问题

问题原因

你的代码存在两个核心错误导致读取到的行内容为空:

  • 缓冲区复用问题:getline()函数如果传入的行指针不为NULL,会直接复用该指针指向的已有缓冲区存储新行内容,不会重新分配内存。你每次循环仅将缓冲区地址赋值给srclns[count++],没有重置lnptr为NULL,导致所有srclns数组中的指针都指向同一块内存地址,后续每次读取新行都会覆盖之前存储的内容。
  • 提前释放内存:循环结束后你直接调用free(lnptr)释放了这块所有srclns指针共同指向的内存,导致srclns中存储的全是野指针,访问野指针属于未定义行为,你遇到的输出空字符串就是该行为的表现之一。

另外还存在隐含的数组越界风险:未判断读取行数超过MAXSRC的情况,读取行数超过20时会出现越界写入。

修复方案
  1. 每次将lnptr赋值给srclns后,立刻将lnptr重置为NULL,让下一次getline调用自动分配新的缓冲区存储新行,避免复用同一块内存。
  2. 仅释放循环结束后未被存入srclns的冗余缓冲区,不要释放已经存入数组的内存,使用完行内容后遍历srclns逐个释放即可。
  3. 补充数组越界检查,避免读取行数超过上限时的越界问题。

修正后代码

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 20:18:03