繁体   English   中英

c setvbuf() 函数调用未按预期工作

[英]c setvbuf() function call not working as expected

我正在学习系统编程,当我运行以下代码时

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char buff[5];
    setvbuf(stderr, buff, _IOFBF, 5);
    for (int i = 1; i < 10; i++) {
        fprintf(stderr, "%d", i);
    }
    _exit(0);
}

setvbuf正在使用 5 字节大小的缓冲区对stderr强加完全缓冲的策略,所以我希望得到12345但它打印1234567 ,这是为什么?

strace-ing 程序显示,当针对 glibc 编译时,它首先写入大小为 1,然后写入大小为 5,最后写入大小为 1:

$ strace -o /dev/stdout -e write,writev ./a.out 2>/dev/null
write(2, "1", 1)                        = 1
write(2, "23456", 5)                    = 5
write(2, "7", 1)                        = 1

使用 musl,它执行 7 次大小为 1 的写入:

$ strace -o /dev/stdout -e write,writev ./a.out 2>/dev/null
writev(2, [{iov_base="1", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="2", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="3", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="4", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="5", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="6", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="7", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="8", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="9", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
+++ exited with 0 +++

因此,很明显,两个 C 库实现都将setvbuf(stream, buf, _IOFBF, size)size参数视为最大值,并且即使在缓冲区已满之前,它们也可以随意刷新缓冲区。

AFAICS 标准中似乎没有任何内容反对这种解释。

暂无
暂无

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

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