setvbuf() – 当buf为NULL时的size参数

看来,当我运行以下代码时:

#include  #include  int main(int argc, char* argv) { int i=0; setvbuf(stdout, NULL, _IOLBF,0); while (1) printf("%d ",i++); return 0; } 

它打印成1024个字符的块,无论我为setvbuf()定义的大小 。 问题是,在这种情况下,如果大小会以某种方式影响,那么1024个字符的定义来自何处。

我不知道你如何识别1024但它可能是BUFSIZBUFSIZstdio.h定义。

如果buf为NULL,则stdio库会自动分配一个缓冲区以供流使用(除非我们选择无缓冲的I / O)。

编辑

这是glibc说的话:

Macro:int BUFSIZ此宏的值是一个整数常量表达式,适用于setvbuf的size参数。 该值保证至少为256

在每个系统上选择BUFSIZ的值,以使流I / O有效。 所以当你调用setvbuf时,最好使用BUFSIZ作为缓冲区的大小。

编辑2

@larsmans是对的。 我看了setvbuf是如何实现的,它在请求行缓冲和呈现NULL buf时忽略了一个调用。 现在, stdout不是普通文件,它附加到终端。 所以,前往pixelbeat

  • 缓冲区大小仅直接影响缓冲模式
  • 像内核这样的默认大小是基于页面大小(我系统上的4096字节)
  • 如果stdin / stdout连接到终端,则默认大小= 1024;
    else size = 4096

根据(草案)C标准,

如果buf不是空指针,则可以使用它指向的数组而不是setvbuf函数分配的缓冲区,参数size指定数组的大小; 否则, size可以确定setvbuf函数分配的缓冲区的大小。 [重点补充。]

因此,假设您测量正确,似乎Glibc可以自由地执行,因为当buf为null时它会令人满意,并且它为您提供1kB缓冲区。 由于您从不写新行,因此行缓冲无效,行为类似于完全缓冲。

大小可能对NULL buf指针没有太大影响。

但是,您仍在使用_IOLBF尝试_IONBF请求缓冲输出。

http://en.wikipedia.org/wiki/Setvbuf