I have the following code to open a input and output file:
if ((source_file_ptr = fopen(source_filename, "rb")) == NULL) {
error("unable to open input file");
}
if ((output_file_ptr = fopen(output_filename, "wb")) == NULL) {
error("unable to open output file");
}
This is goood simple way to catch errors in opening the files.
However after some editing overall to my program, the program now crashes instead of catching an invalid output file.
I tried a several things without success but interestingly when I try this:
if ((output_file_ptr = fopen(output_filename, "wb")) == NULL) printf("fail");
exit(0);
if ((source_file_ptr = fopen(source_filename, "rb")) == NULL) {
error("unable to open input file");
}
if ((output_file_ptr = fopen(output_filename, "wb")) == NULL) {
error("unable to open output file");
}
It will print “fail” (and obviously exit without much more insight).
But if I comment out the exit(0) line, it will again exhibit the same crash behaviour without printing “fail” nor catching the error.
I can’t explain why this is… I suspected a dangling pointer but the only preceding lines of code within the function are already enclosed in if-else if-else all with braces. There are only a few other functions delcared above but I’ve checked and ensured they’re all enclosed in braces.
I’m still learning C, any thoughts on what’s going on here?
Thanks as a lot!
Note: enclosing printf(“fail”) with braces doesn’t alter the behaviour I observe.
EDIT: additional code that follows the above:
if (fread(&file_struct, sizeof(file_struct), 1, source_file_ptr) < 1) {
error("unable to read %s", source_filename);
}
else {
error_check(file_struct);
if (fwrite(&file_struct, sizeof(file_struct), 1, output_file_ptr) < 1) {
error("unable to write file header");
}
}
The first thing I’d check is that
source_filenamewas a valid C string. I’d then checkoutput_filenamein the same way.If it turns out your changes have somehow corrupted either or both of them, you’re into undefined territory behaviour.
The use of a debugger would be ideal here since you could set a breakpoint at the start of that code then single-step through, checking variables that you’re about to use.
The other thing you should check is whether your calls to
erroractually return (rather than, for example, callexit).If they do then, even though the
fopencalls returned NULL, you’re still going to pass that tofreadand/orfwrite, a definite no-no.Since your second case prints
"fail", it’s a given that you have some problem opening the output file. Using the NULL handle from that would not be a good thing.If that function does return, then you should be using something like: