c – 谁自由的setvbuf缓冲区?

所以我一直在深入研究如何实现libc的stdio部分,并且我遇到了另一个问题.看着man setvbuf我看到以下内容

When the first I/O operation occurs on
a file,malloc(3) is called,and a
buffer is obtained.

这是有道理的,除非你实际使用它,否则你的程序中不应该有I / O的malloc.我对此的直觉反应是,libc将在这里清理它自己的烂摊子.我只能假设它是因为valgrind报告没有内存泄漏(他们当然可以做一些肮脏的事情而不是直接通过malloc分配它……但我们假设它现在使用malloc).

但是,你也可以指定自己的缓冲区……

int main() {
    char *p = malloc(100);
    setvbuf(stdio,p,_IOFBF,100);
    puts("hello world");
}

哦不,内存泄漏!瓦尔格林德证实了这一点.因此,似乎每当stdio自己分配一个缓冲区时,它就会被自动删除(最迟在程序退出时,但可能在流程上关闭).但是如果你明确指定缓冲区,那么你必须自己清理它.

虽然有一个问题.该手册页也说明了这一点:

You must make sure that the space that
buf points to still exists by the time
stream is closed,which also happens
at program termination. For example,
the following is invalid:

在这对于标准流来说变得越来越有趣.如何正确清理手动分配的缓冲区,因为它们在程序终止时关闭?我可以想象一下文件结构中的“当我关闭标志时清理它”,但是它会变得毛茸茸,因为如果我读到这个就做这样的事情:

setvbuf(stdout,0);
printf("hello ");
setvbuf(stdout,_IOLBF,0);
printf("world\n");

由于这句话,标准库将导致2次分配:

If the argument buf is NULL,only the
mode is affected; a new buffer will be
allocated on the next read or write
operation.

编辑:我的问题的附录.因为很明显我必须释放我传递给setvbuf的任何缓冲区,如果我确实在stdout上使用它是否有任何实用的方法来释放它?它必须活到程序结束.我能想到的最好的是fclose(stdout)然后释放它或使用静态缓冲区,就像有人提到的那样.我问,因为这似乎是一个尴尬的设计决定.

解决方法

也是从 man page(至少在我的系统上):

If buf is not NULL,it is the caller’s responsibility to free(3) this buffer after closing the stream.

也就是说,你摩托了它,你释放它.

退出之前,您可以自己关闭流,从而允许您释放缓冲区.或者,您可以刷新流并使用NULL缓冲区参数再次调用setvbuf以切换回库管理缓冲区或无缓冲I / O.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...