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

在while循环中使用getline()读取文件是否属于不良编程实践?

问题

如果我需要处理一个几乎每行都包含\n换行符的文件,在while循环中调用getline()读取文件内容是否属于不良编程实践?
我目前的理解是,每遇到一个\n字符就会调用一次getline(),而每次调用都会触发realloc()内存重分配操作,这种实现方式是否效率低下?

提问附示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
    FILE *fp = fopen("file.txt", "r");
    if (fp == NULL) {
        perror("Unable to open file: ");
        exit(1);
    }
    char *buffer = NULL;
    size_t len = 0;
    ssize_t characters;

    while ((characters = getline(&buffer, &len, fp)) != -1) {
        fputs(buffer, stdout);
    }
    fclose(fp);
    free(buffer);
    buffer = NULL;
    return 0;
}
回答

这种写法不属于不良编程实践,你对getline()的内存分配逻辑存在误解:

  • getline()并非每次读取一行都会调用realloc(),只有当前传入的缓冲区长度不足以容纳当前行内容时,才会触发扩容。你给出的示例代码中buffer初始为NULL、len初始为0,第一次调用时会分配一块初始大小的内存,后续读取的行只要长度不超过当前缓冲区已分配的长度,就不会产生任何内存重分配开销。
  • 对于几乎所有普通文本文件——哪怕每行都很短、换行符非常密集——只要行长度没有明显的跳变,getline()通常只会在最开始的数次调用中完成缓冲区扩容,后续整个读取循环都不会再触发realloc(),额外开销极低,根本不存在效率低下的问题。
  • 就算遇到行长度波动较大的极端场景,getline()的扩容逻辑也是经过glibc等标准库实现反复优化的,一般按2的幂次阶梯扩容,摊还时间复杂度为O(n),和你手动申请大缓冲区、逐块读取的实现效率没有量级差距,同时还自动帮你处理了缓冲区边界判断、换行符识别、内存动态调整等容易写出bug的细节,代码健壮性和可读性反而更好。

只有当你完全不需要按行维度处理内容,只需要对文件做全量无差别的流式拷贝或批量处理时,才需要考虑换用fread()按固定块大小读取——这种替换只是场景适配,为了省掉逐字符判断换行符的少量开销,不是因为getline()本身的实现效率差。
你贴出的示例代码是getline()的标准合规用法,没有任何问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:24:21