当我将0作为getline的第二个参数传递时会发生什么?

时间:2019-05-24 05:12:47

标签: c io getline

cplusplus.com指出,getline函数的第二个参数是

  

要写入s的最大字符数

但是,我看过这样的代码:

size_t linecap = 0;
ssize_t linelen;
linelen = getline(&line, &linecap, fp);

这不是从源读取0个字节吗?还是还有其他事情发生?

2 个答案:

答案 0 :(得分:6)

不,这是不正确的。从man page,(强调我的

  

如果*lineptrNULL,则getline()将分配一个缓冲区来存储行,该行应由用户程序释放。 (在这种情况下,*n中的值将被忽略。)

     

或者,在调用getline()之前,*lineptr可以包含一个指向malloc(3)分配的缓冲区*n字节大小的指针。如果缓冲区的大小不足以容纳该行,则getline()realloc(3)调整其大小,并根据需要更新*lineptr*n

     

无论哪种情况,在成功调用后,*lineptr*n都会被更新以分别反映缓冲区地址和分配的大小。

因此,第二个参数所指向的内存中存储的初始值对实际扫描没有影响。扫描值并将其填充到缓冲区后,

  • 函数返回值将告诉您扫描输入的大小(以字节为单位)。
  • *n的值将告诉您分配给存储输入的缓冲区的大小(通常大于扫描的输入的大小)。

答案 1 :(得分:3)

getline的想法是,重新分配的数量应尽可能少,因为对malloc的调用往往很昂贵。因此,如果您反复使用getline来读取文件中的行,重复使用相同的缓冲区和长度,则缓冲区最终将增长到文件中最长的行的大小,并且不需要重新分配最长的线之后的线。

但是要使其正常工作,必须遵循某些合同-即,如果*lineptr非NULL ,则为

  • 必须是malloc返回的指针
  • 必须具有至少*n个字节的分配大小

推论:在以下两种情况下,通过0中的*n是可以的:

  • 如果*lineptrNULL
  • *lineptrmalloc返回的任何活动指针(因为malloc返回的任何指针将具有0个字节的空间)。

在两种情况下,*n将被更新为行的长度,并且realloc(*lineptr, new_line_length_with_terminator)的返回值(如果成功)将被分配给*lineptr

当然