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

C语言封装读文件到字符串数组的函数后出现段错误如何排查

问题根因

段错误的直接原因是运算符优先级错误:C语言中[]下标运算符的优先级高于*解引用运算符,你在函数中写的*rows[i]实际等价于*(rows[i]),完全不符合预期逻辑。你想要的是先对入参rows(三级指针)解引用得到存储行的char**数组,再取下标i的元素,正确写法应该是(*rows)[i]。

额外还有一个不必要的设计问题:你传入了FILE**二级文件指针,但函数内部并没有修改FILE指针本身的值,完全不需要传二级指针,直接传FILE*即可。

修复后的完整代码
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t readFile(FILE *fp, char ***rows)
{
  char *lineBuf = NULL;
  size_t n = 0;
  size_t nLines = 0;
  ssize_t lineLength = 0;
  size_t i = 0;

  while ((lineLength = getline(&lineBuf, &n, fp)) != -1)
  {
    lineBuf[strcspn(lineBuf, "\n")] = 0;
    lineBuf[strcspn(lineBuf, "\r")] = 0;

    // 修正优先级问题,先解引用rows再取下标
    (*rows)[i] = malloc(lineLength + 1);
    strcpy((*rows)[i], lineBuf);
    i++;
    nLines = i;
    char **temp = realloc(*rows, (nLines + 1) * sizeof(char *));
    // 增加realloc失败判断,避免内存泄漏
    if (temp == NULL) {
        perror("realloc failed");
        // 可补充已分配内存的释放逻辑,进一步避免泄漏
        break;
    }
    *rows = temp;
  }
  // 释放getline分配的缓冲区
  free(lineBuf);
  return nLines;
}

int main(int argc, char **argv)
{
  if (argc != 2)
  {
    fprintf(stderr, "Please supply a file path:\n%s <file path>\n", argv[0]);
    return EXIT_FAILURE;
  }
  FILE *fp = fopen(argv[1], "r");
  if (!fp)
  {
    perror("ERROR");
    return EXIT_FAILURE;
  }

  char **rows = malloc(sizeof(char *));
  // 直接传FILE*即可,不需要传二级指针
  size_t nLines = readFile(fp, &rows);

  printf("nLines: %lu\n", nLines);
  if (nLines >= 1) printf("row 1: %s\n", rows[0]);
  if (nLines >= 2) printf("row 2: %s\n", rows[1]);

  // 最后记得释放rows数组和每个行的内存、关闭文件,避免泄漏
  for (size_t i = 0; i < nLines; i++) {
      free(rows[i]);
  }
  free(rows);
  fclose(fp);
  return 0;
}
其他优化说明
  • 新增了realloc返回值判断,避免分配失败时直接覆盖原指针导致内存泄漏
  • 新增了getline分配的lineBuf的释放逻辑,避免内存泄漏
  • 新增了数组下标访问的边界判断,避免文件行数不足时访问越界
  • 移除了malloc/realloc返回值的强制转换,C语言中该转换是非必要的,反而可能隐藏隐含错误

内容的提问来源于stack exchange,提问作者Max888

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 06:15:02