为什么我应该使用自己的缓冲区来获取getline或类似函数?

时间:2015-01-04 20:20:37

标签: c buffer getline

前几天我正在编写一个程序,我使用getline()函数,我意识到以前从未想过的东西,并且无法在网上找到任何关于它的东西。

根据手册页中getline的描述:

  

说明

     

getdelim()函数从流中读取一行,由字符分隔符分隔。 getline()函数等效于getdelim(),换行符为分隔符。除非到达文件的末尾,否则分隔符字符作为行的一部分包含在内。

     

调用者可以为*linep中的行提供指向malloced缓冲区的指针,以及*linecapp中该缓冲区的容量。这些函数根据需要扩展缓冲区,就像通过realloc()一样。如果linep指向NULL指针,则将分配新缓冲区。在任何一种情况下,*linep*linecapp都会相应更新。

通常当我使用这个函数时,我总是将我自己的缓冲区malloc并传递给getline函数,但在阅读之后我意识到这不是必需的,因为只会创建一个。

我的问题是:我有没有理由创建自己的缓冲区,然后将其传递给getline,而不是仅传递NULL并让getline处理缓冲区?

我能想到的唯一原因是,如果你想控制缓冲区的大小,但这看起来并不正确,因为它说它会根据需要调整缓冲区的大小。

我什么时候应该使用自己的缓冲区?何时我应该让getline处理缓冲区的创建?

2 个答案:

答案 0 :(得分:4)

问:有什么理由我应该创建自己的缓冲区,然后将其传递给getline,而不是只传递NULL并让getline处理缓冲区?
答:通常,没有。在某些选择情况下,在调用getline()之前进行分配是有意义的。

1)许多getline()重新分配方案是班轮。也就是说,它将分配N个字节的缓冲区(例如256,1k,4k)。然后,如果它不够大,它将尝试2 * N,3 * N,4 * N,5 * N等。如果由于某种原因,代码需要定期大的缓冲区需求,在调用之前分配一个大缓冲区{{ 1}}将阻止getline()重复重置小缓冲区。潜力,如果可疑,效率提高。

getline()

2)在调用 size_t size = 10000; char *buf = mallc(size); ssize_t numchar = getline(&buf, &size, ...); 之前,代码是否需要或有可用的工作缓冲区,可以使用它。

getline()

3)重复通话。这包括重复调用 size_t size = 100; char *buf = mallc(size); ... foo(buf, size); ... // No need for these steps // free(buf); // size = 0; // buf = NULL; ... ssize_t numchar = getline(&buf, &size, ...); ... free(buf); 的循环。无需在循环内释放,等待循环完成。 @Alan Stokes

getline()

Q2:我什么时候应该使用自己的缓冲区?何时我应该让getline处理缓冲区的创建? A2:当代码当然需要或从中受益时,分配您自己的缓冲区。否则让 // do not use this while (some_condition) { size_t size = 0; char *buf = NULL; ssize_t numchar = getline(&buf, &size, ...); foo(numchar, buf,size); free(buf); } // instead, use this model size_t size = 0; char *buf = NULL; while (some_condition) { ssize_t numchar = getline(&buf, &size, ...); foo(numchar, buf,size); } free(buf); 去做。

答案 1 :(得分:0)

  1. 没有理由,缓冲区是realloc d根据需要,您应该自己free。因此,您可以通过NULL确保通过length == 0

  2. 我没有看到使用您自己分配的缓冲区的任何情况,无论如何都会使用mallocgetline getdelim也会使用

  3. 当然,如果您传递足够大的缓冲区,则会阻止在每个realloc上调用getline,但您可以使用valgrind进行测试,而对于最常见的情况,则会尽可能少可能致电realloc