【发布时间】:2021-01-05 06:32:24
【问题描述】:
当我在我的 Mac 上运行如下所示的 APUE 示例代码时,它会引发 EXC_BAD_ACCESS 异常。我检查了文件光标,它位于正确的位置 12。我什至尝试用fputc 替换fprintf。之后,它工作正常并且异常消失了。但我想知道外面发生了什么以及为什么。
#include "apue.h"
#define BSZ 48
int main(){
FILE *fp;
char buf[BSZ];
memset(buf,'a',BSZ-2);
buf[BSZ-2]='\0';
buf[BSZ-1]='X';
if ((fp = fmemopen(buf,BSZ,"w+")) == NULL)
err_sys("fmemopen failed");
printf("initial buffer contents: %s\n",buf);
fprintf(fp, "hello, world");
printf("before flush: %s\n", buf);
fflush(fp);
printf("after fflush: %s\n",buf);
printf("len of string in buf = %ld\n",(long)strlen(buf));
memset(buf,'b', BSZ-2);
buf[BSZ-2]='\0';
buf[BSZ-1]='X';
fprintf(buf, "hello, world");
// fputc('a',fp);
fseek(fp,0,SEEK_SET);
printf("after fseek: %s\n",buf);
printf("len of string in buf = %ld\n", (long)strlen(buf));
}
控制台输出如下:
/Users/heping/Documents/APUE-Example-Code/stdio/cmake-build-debug/memstr
initial buffer contents:
before flush: hello, world
after fflush: hello, world
len of string in buf = 12
Exception: EXC_BAD_ACCESS (code=1, address=0x8)
Process finished with exit code 9
最后一个堆栈帧是这样的:我认为文件锁定似乎有问题。
【问题讨论】:
-
嗨,有趣,大概是 BSZ 的大小?
-
@IronMan 我不这么认为,因为缓冲区有 48 字节大,文件光标位于 12 字节位置。我想写的字符串是12字节长,所以写操作后的总长度不会超过48字节长。正确的?更重要的是,如果我用 fputc 替换 fprintf,一切都很有趣。 :)
-
您在
fprintf语句中不小心将char buf[48];作为FILE*参数传递了。这就是它崩溃的原因。因为我使用了-Werror,所以我的编译器阻止了我执行程序。 -
@Neal.Marlin: (a) 除了
err_sys函数之外,它不是整个程序。它缺少BSZ的定义并包含多个标头。 (b) 由于缺少err_sys,因此它不是minimal reproducible example。提供完整可重现示例的一个原因是,其他人可以轻松地运行该程序以进行自己的测试和调试。仅仅声称缺少的部分是什么是不够的。询问时,您应该提供 everything 或重写示例以不需要您省略的部分。遵循指南并帮助人们帮助您。