为何未使用的FILE指针会引发bus error错误?
未使用的FILE* out指针引发Bus Error的原因分析
先看你提供的代码:
void merge_files(){ FILE *in1, *in2, *out; char *inName1 = "Text_4_input1.txt"; char *inName2 = "Text_4_input2.txt"; char *buffer; int n = 100; if ( (in1 = fopen (inName1, "r")) == NULL ) { printf ("Can't open %s for reading.\n", inName1); } if ( (in2 = fopen (inName2, "r")) == NULL ) { printf ("Can't open %s for reading.\n", inName2); } while (fgets (buffer, n, in1 ) != NULL) { fputs (buffer, stdout); if ( fgets (buffer, n, in2) != NULL ) { printf ("a"); fputs (buffer, stdout); } } while (fgets (buffer, n , in2 ) != NULL ) fputs (buffer, stdout); fclose (in1); fclose (in2); }
核心问题:未初始化的buffer指针才是罪魁祸首
你看到的“移除FILE *out就正常”只是巧合,Bus Error的真正原因是**char *buffer没有被初始化,属于野指针**。fgets需要往一块可写的内存区域写入数据,但你只声明了指针,没给它分配内存(不管是栈上还是堆上),这时候buffer指向的是内存里的随机地址——如果这个地址是非法的(比如未映射的内存段、只读内存),就会触发Bus Error;如果碰巧指向了一块可写的内存(比如栈上的其他空间),代码可能暂时“正常”运行,但这完全是运气,随时可能崩溃。
为什么移除out后代码能运行?
这是C语言未定义行为的典型表现:栈上变量的布局由编译器决定,当你声明FILE *out时,它在栈上占了8字节(64位系统),改变了buffer这个野指针的初始随机值,刚好让它指向了非法内存,触发错误;移除out后,栈布局变化,buffer的随机值碰巧指向了一块可写区域,所以代码暂时能跑,但这绝对不是正确的修复方式。
正确的修复步骤
给
buffer分配内存:- 最简单的方式是用栈数组:
char buffer[100];(和你定义的n=100对应); - 或者用堆内存:
char *buffer = malloc(n);,记得在函数结束前用free(buffer);释放。
- 最简单的方式是用栈数组:
修复文件打开失败后的逻辑:
如果fopen失败,in1或in2会是NULL,后续的fgets和fclose操作空指针会触发新的错误,应该在打开失败后直接返回:if ( (in1 = fopen (inName1, "r")) == NULL ) { printf ("Can't open %s for reading.\n", inName1); return; // 直接返回,避免后续错误操作 }给第二个while循环加上花括号:
虽然语法上没问题,但不加花括号的单语句循环可读性差,容易后续修改代码时出错:while (fgets (buffer, n , in2 ) != NULL ) { fputs (buffer, stdout); }
内容的提问来源于stack exchange,提问作者Anh Duc Nguyen
相关产品推荐
相关产品推荐

