繁体   English   中英

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

[英]setvbuf() - buffer size when buf is NULL

我已经读过类似 问题的答案,但是对文件执行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;
}

它打印BUFSIZ =8192。据我了解,BUFSIZ应该是glibc使用的值,它代表fopen之后默认创建的缓冲区的大小(据我了解,应该与调用NULL指针的setvbuf相同)到参数buf)。 我使用massif运行了该程序,输出清楚地表明glibc分配的缓冲区长4096字节

地块输出

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

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

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

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

长答案:让我们追溯一下当让NULL指针作为buf传递时setvbuf的作用。

https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/iosetvbuf.c#l60

_IO_DOALLOCATE (fp)

https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/libioP.h#l237

#define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP)

在这里,它使用JUMP0宏调用与FILE vtable相关的“ __doallocate”函数,并且最终调用了在此定义的_IO_file_doallocate()

https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/filedoalloc.c#l97

#if _IO_HAVE_ST_BLKSIZE
    if (st.st_blksize > 0 && st.st_blksize < _IO_BUFSIZ)
        size = st.st_blksize;
#endif

在上述行中,您可以看到我在简短答案中提到的内容。 它使用stat64结构( https://linux.die.net/man/2/stat64 )检索文件系统的块大小,并在小于BUFSIZ的情况下相应地设置大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM