C setvbuf()-buf为空时的缓冲区大小

C setvbuf()-buf为空时的缓冲区大小,c,io,buffer,C,Io,Buffer,我已经阅读了一篇类似文章的答案,但我更感兴趣的是对文件执行I/O时的流缓冲 当我运行以下代码时 #include <stdio.h> int main(void) { printf("%d\n", BUFSIZ); FILE *fp = fopen("ekomi.txt", "wb"); char array[2] = {'a', 'b'}; fwrite(array, sizeof(char), 2, fp); fclose(fp);

我已经阅读了一篇类似文章的答案,但我更感兴趣的是对文件执行I/O时的流缓冲

当我运行以下代码时

#include <stdio.h>

int main(void) {

    printf("%d\n", BUFSIZ);

    FILE *fp = fopen("ekomi.txt", "wb");

    char array[2] = {'a', 'b'};
    fwrite(array, sizeof(char), 2, fp);
    fclose(fp);

    return 0;
}
#包括
内部主(空){
printf(“%d\n”,BUFSIZ);
文件*fp=fopen(“ekomi.txt”、“wb”);
字符数组[2]={'a','b'};
fwrite(数组,sizeof(char),2,fp);
fclose(fp);
返回0;
}
它打印BUFSIZ=8192。 据我所知,BUFSIZ应该是glibc在fopen之后默认创建的缓冲区大小所使用的值(据我所知,这应该与调用setvbuf传递参数buf的空指针相同)。 我用massif运行了这个程序,输出清楚地显示glibc分配的缓冲区是4096字节长

GNU C库文档本身不清楚缓冲区的默认大小:

如果指定null指针作为buf参数,则setvbuf使用malloc分配缓冲区本身。关闭流时,将释放此缓冲区


所以我的问题是,glibc如何决定为缓冲区分配多少内存?

简短回答:BUFSIZ是允许的最大缓冲区大小,但malloc中使用的是由文件系统块大小给出的

长答覆: 让我们追溯一下setvbuf在将空指针作为buf传递时所做的工作

在这里,它调用了一个“\u doallocate”函数,该函数与带有JUMP0宏的文件vtable关联,最后它调用了\u IO\u FILE\u doallocate(),定义如下:

#如果(如果)你有
如果(st.st_blksize>0和st.st_blksize<\u IO_BUFSIZ)
尺寸=st.st\U blksize;
#恩迪夫

在前面的一行中,你可以看到我在简短回答中提到的内容。它使用stat64struct()检索文件系统的blocksize,如果小于BUFSIZ,则相应地设置大小

谢谢,这很有道理。
_IO_DOALLOCATE (fp)
#define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP)
#if _IO_HAVE_ST_BLKSIZE
    if (st.st_blksize > 0 && st.st_blksize < _IO_BUFSIZ)
        size = st.st_blksize;
#endif