缓冲与内存分配

← 返回 MOC | ← 主页


#include <stdio.h>

main()
{
    int c;
    char buf[BUFSIZ];
    setbuf(stdout, buf);

    while ((c = getchar()) != EOF)
        putchar(c);
}
这段代码块有错误,你能找到吗

核心陷阱:“人走了,信箱拆了,但信还没发”

书中例子的错误逻辑如下:

  1. 分配空间 :在 main 函数里定义了一个局部变量 char buf[BUFSIZ](在上)。
  2. 建立连接 :调用 setbuf(stdout, buf),告诉系统:“以后往屏幕印东西,先存在我这个 buf 里,等存满了再一起印。”
  3. 函数结束main 函数执行完了,准备关门走人。此时,局部变量 buf 作为“房客”,它的 生命周期结束,空间被系统回收了
  4. 致命一击 :C 语言的运行环境在 main 结束之后,会自动做一次“大扫除”(清理所有输出流)。它发现 stdout 还有个缓冲区 buf 没清空,于是试图把最后一点数据发出。

结果 :此时 buf 所在的内存已经是“非法地带”了。程序试图访问一个已经不存在的变量,直接 Segment Fault 崩溃

方案做法效果
方案 A:静态化static char buf[BUFSIZ];变量不再存在栈里,而是存在静态区 ,它会活得和程序一样长。
方案 B:动态分配char *buf = malloc(BUFSIZ);除非你手动 free,否则它在堆里一直有效(最推荐)。
方案 C:全局化buf定义在 main函数外面。同样让它的生命周期覆盖整个程序运行期。