以下代码在ubuntu上构建时会创建一个可执行文件。
#include <stdio.h>
void otherfunc(FILE* fout){
fclose(fout);//Line 4
fout = fopen("test.txt", "w");//Delete contents and create a new file//Line 5
setbuf(fout, 0);//Line 6
}
int main() {
FILE *fout = fopen("test.txt", "r");//Line 10
if (fout) {
//file exists and can be opened
fclose(fout);//Line 13
fout = fopen("test.txt", "a");//Line 14
setbuf(fout, 0);
}
else {
//file doesn't exists or cannot be opened
fout = fopen("test.txt", "a");//Line 19
}
otherfunc(fout);//Line 22
fclose(fout);//Line 24
return 0;
}
当通过valgrind运行时,valgrind会发出以下警告:
== 13569 ==读取大小4无效
== 13569 ==在0x4EA7264:fclose @@ GLIBC_2.2.5(iofclose.c:53)
== 13569 == by 0x400673:main(newmain.cpp:24)
== 13569 ==地址0x52042b0是一个大小为552的块中的0字节free'd
== 13569 ==在0x4C2EDEB:free(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
== 13569 == by 0x4EA7362:fclose @@ GLIBC_2.2.5(iofclose.c:84)
== 13569 == by 0x4005CD:otherfunc(_IO_FILE *)(newmain.cpp:4)
== 13569 == by 0x400667:main(newmain.cpp:22)
== 13569 ==在
分配了阻止== 13569 ==在0x4C2DB8F:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
== 13569 == by 0x4EA7CDC:__ fopen_internal(iofopen.c:69)
== 13569 == by 0x400657:main(newmain.cpp:19)
基本上,它抱怨第24行的fclose(fout);
正在关闭fclose(fout);
内第4行otherfunc()
上已释放的已释放内存。但第24行fclose(fout);
旨在关闭第5行所执行的fopen()
。
在代码中的任何时间点,只要调用fclose()
,就会始终只有一个打开fopen()
。那么为什么这是valgrind报告的无效读取?
答案 0 :(得分:3)
otherfunc
按值获取文件指针。因此,从otherfunc
返回后,您在第5行分配的值将丢失,当它返回main
时,fout
的值将保持不变。它包含您在第4行关闭的悬空文件指针值。因此,第24行的close
调用将收到无效指针。