问题描述
我用fclose()
关闭流后遇到了fwrite()
成功的奇怪行为,但是由于fflush()
失败,文件未被覆盖.
I've encountered a strange behavior that is fwrite()
succeeds after I close the stream with fclose()
but the file is not overwritten as fflush()
fails.
我的代码是:
int main(int argc, char* argv[])
{
FILE* file = fopen("file.txt", "w");
if(!file) perror("Cannot open the file.\n");
char text[] = "1234567";
fclose(file);
int count_of_written_objects = fwrite(text, sizeof(text),1, file);
printf("Count of written objects into the file: %d \n", count_of_written_objects);
if(count_of_written_objects != 1) perror("Not expected count of objects was written.\n");
int success = fflush(file);
printf("Variable success: %d \n", success);
if(success == EOF) perror("Flush did not succeed. \n");
return 0;
}
它提供以下输出:
Count of written objects into the file: 1
Variable success: -1
Flush did not succeed.
: Bad file descriptor
关闭流时,fwrite()
如何成功? fwrite()
可以在关闭的流上写吗?你能给我解释一下吗?
How can fwrite()
succeed when the stream is closed? Can fwrite()
write on the closed stream? Could you explain it to me?
推荐答案
在关闭文件后尝试对文件执行任何操作,您正在处理未定义的行为.
Attempting to do any operations on a file after it has been closed, you are dealing with undefined behaviour.
库实现者假定以特定顺序发出调用是调用者的责任,因此,库可能会或可能不会尝试验证不正确的情况.这种情况下的验证主要是出于性能和减小代码大小的目的而被忽略.
The library implementer assumes that it is the responsibility of the caller to issue the calls in a certain order, hence the library may or may not try to validate the cases where that isn't true. Validation for such cases is ignored mostly for performance and reducing the code size.
如果您尝试写入以前free
的存储位置,也会发生相同的情况.即使看起来一切正常,您仍在调用未定义的行为.
The same thing will happen if you attempt to write to a memory location that has been previously free
'd. Even though it may seem as if everything works correctly, you are invoking undefined behaviour.
从技术上讲,在特定情况下,写操作不可能成功,因为库函数fclose
最有可能在基础描述符上调用close
系统调用,并随后调用任何write
系统对该描述符的调用(最终由fwrite
调用)应该失败,因为它将被内核拒绝.
Technically speaking, in the particular case it shouldn't be possible for the write to succeed, because the library function fclose
will most probably call the close
system call on the underlying descriptor, and any subsequent write
system calls to that descriptor (eventually invoked by fwrite
) should fail because it will be rejected by the kernel.
这篇关于fclose()之后,fwrite()成功的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!