Reputation: 7691
I ran across the following code in one of our in-house dlls and I am trying to understand the behavior it was showing:
long GetFD(long* fd, const char* fileName, const char* mode)
{
string fileMode;
if (strlen(mode) == 0 || tolower(mode[0]) == 'w' || tolower(mode[0]) == 'o')
fileMode = string("w");
else if (tolower(mode[0]) == 'a')
fileMode = string("a");
else if (tolower(mode[0]) == 'r')
fileMode = string("r");
else
return -1;
FILE* ofp;
ofp = fopen(fileName, fileMode.c_str());
if (! ofp)
return -1;
*fd = (long)_fileno(ofp);
if (*fd < 0)
return -1;
return 0;
}
long CloseFD(long fd)
{
close((int)fd);
return 0;
}
After repeated calling of GetFD with the appropriate CloseFD, the whole dll would no longer be able to do any file IO. I wrote a tester program and found that I could GetFD 509 times, but the 510th time would error.
Using Process Explorer, the number of Handles did not increase.
So it seems that the dll is reaching the limit for the number of open files; setting _setmaxstdio(2048)
does increase the amount of times we can call GetFD. Obviously, the close() is working quite right.
After a bit of searching, I replaced the fopen()
call with:
long GetFD(long* fd, const char* fileName, const char* mode)
{
*fd = (long)open(fileName, 2);
if (*fd < 0)
return -1;
return 0;
}
Now, repeatedly calling GetFD/CloseFD works.
What is going on here?
Upvotes: 4
Views: 6272
Reputation: 376
you are open the file fopen() function so u have to close the file useing fclose(), if you are using open() function and try to call fclose() function it will not work
Upvotes: 2
Reputation: 2182
fopen
opens it's own file descriptor, so you'd need to do an fclose(ofp)
in your original function to prevent running out of file descriptors. Usually, one either uses the lower level file descriptor functions open, close
OR the buffered fopen, fclose
functions.
Upvotes: 3
Reputation: 47052
The standard library you are using has a static array of FILE
structures. Because you are not calling fclose()
, the standard library doesn't know that the underlying files have been closed, so it doesn't know it can reuse the corresponding FILE
structures. You get an error after it has run out of entries in the FILE
array.
Upvotes: 5
Reputation: 213029
You need to use fclose
with files opened via fopen
, or close
with files opened via open
.
Upvotes: 8
Reputation: 35594
If you open a file with fopen
, you have to close it with fclose
, symmetrically.
The C++ runtime must be given a chance to clean up/deallocate its inner file-related structures.
Upvotes: 17