缓冲与内存分配
#include <stdio.h>
main()
{
int c;
char buf[BUFSIZ];
setbuf(stdout, buf);
while ((c = getchar()) != EOF)
putchar(c);
}
这段代码块有错误,你能找到吗
核心陷阱:“人走了,信箱拆了,但信还没发”
书中例子的错误逻辑如下:
- 分配空间 :在
main函数里定义了一个局部变量char buf[BUFSIZ](在栈上)。 - 建立连接 :调用
setbuf(stdout, buf),告诉系统:“以后往屏幕印东西,先存在我这个buf里,等存满了再一起印。” - 函数结束 :
main函数执行完了,准备关门走人。此时,局部变量buf作为“房客”,它的 生命周期结束,空间被系统回收了 。 - 致命一击 :C 语言的运行环境在
main结束之后,会自动做一次“大扫除”(清理所有输出流)。它发现stdout还有个缓冲区buf没清空,于是试图把最后一点数据发出。
结果 :此时 buf 所在的内存已经是“非法地带”了。程序试图访问一个已经不存在的变量,直接 Segment Fault 崩溃
| 方案 | 做法 | 效果 |
|---|---|---|
| 方案 A:静态化 | static char buf[BUFSIZ]; | 变量不再存在栈里,而是存在静态区 ,它会活得和程序一样长。 |
| 方案 B:动态分配 | char *buf = malloc(BUFSIZ); | 除非你手动 free,否则它在堆里一直有效(最推荐)。 |
| 方案 C:全局化 | 把 buf定义在 main函数外面。 | 同样让它的生命周期覆盖整个程序运行期。 |