Einheri
Einheri

Reputation: 985

fclose() causing a crash in windows

For some reason fclose() seems to be causing an error in a program I'm writing. The windows terminal says "process returned 255" when it happens. Below is part of the code:

FILE* output = fopen("random.txt","w");
write(c,output);
//fprintf(output,"shit\n");
fclose(output);

"write" basically writes things into the output file. Even when the program crashes, the data gets output into the file. After the writing operation I can still write to the output file and the text will be there if I do, but somehow closing the file causes an error. Could someone please explain to me what the error code might mean (if anything), and how this error might be solved? Thank you.

EDIT: "write()" writes to the output file and that's all; the only thing it does with the output file is fprintf-ing. It returns nothing because it's a void function. Didn't get to see what fclose() returns because apparently the program crashes before I can check the return value :\

EDIT: Below is the specifics of "write()". I changed it to "write_insult()" to avoid confusion with the system call.

void write_insult(Composite c,FILE* output){
printf("lol\n");
switch (c->type){
    case SENTENCE:{
        writeSentence(c,output);
        break;
    }
    default: break;
}

}

void writeSentence(Composite c,FILE* output){
FILE* source;
int random = 0;
char* fileName = NULL;
int i = 0;
char* number = malloc(sizeof(char)*2);
if (c->subtype < 10){
    number[0] = '0';
    sprintf(number+1,"%d\0",c->subtype);
}else{
    sprintf(number,"%d\0",c->subtype);
}

fileName = malloc(sizeof(char)*17);
strcpy(fileName,"res/SEN/  /  .txt");
fileName[8] = number[0];
fileName[9] = number[1];
fileName[11] = '0';
fileName[12] = '0';
FILE* tester = NULL;
while ((tester = fopen(fileName,"r")) != NULL){
    i++;
    fclose(tester);
    if (i < 10){
        fileName[12]++;
    }else{
        fileName[11]++;
        fileName[12] = '0';
        i = 0;
    }
}
random = rand()%i;
if (random < 10){
    number[0] = '0';
    sprintf(number+1,"%d\0",random);
}else{
    sprintf(number,"%d\0",random);
}
fileName[11] = number[0];
fileName[12] = number[1];
fileName[17] = 0;
source = fopen(fileName,"r");
Table t = parseFile(source); //remember to free
i = 0;
char* word = NULL;
while (i < t->num){
    if (isInt(t->content[i])){
        word = chooseWord(atoi(t->content[i]));
    }else{
        word = t->content[i];
    }
    fprintf(output,"%s ",word);
    i++;
}
fclose(source);
destroyTable(t);

}

EDIT: I fixed all the string issues, and the error persists. By the way, if I instead declare the file pointer inside the writeSentence function instead of opening the file beforehand passing it in, and close it before the function stops, somehow it's all fine. The compiler is the one that comes with Pelles C, by the way. It did some wonky things before, so could it be that the fault is not on me?

EDIT: perhaps I should condense the question by asking instead: under what circumstances might fprintf work perfectly on a file opened for writing, but not fclose, which crashes before it could even generate a return value?

EDIT: Thanks, folks, for all the kind help and advice; I found out I've got an unwanted fopen operation somewhere in the code. That seems to be it, for the problem is gone.

Upvotes: 0

Views: 3744

Answers (4)

Einheri
Einheri

Reputation: 985

Sorry, didn't know how things work around here. I didn't have more progress investigating what exactly caused the crash or what fclose is returning, but it seems there's an unwanted fopen operation somewhere in the code. For some reason that seems to be the culprit, as the problem is now gone. Thank you all for your help

Upvotes: 0

Ingo Leonhardt
Ingo Leonhardt

Reputation: 9904

 fileName = malloc(sizeof(char)*17)

is exactly one char to short (forgot the '\0'?). Maybe that's all

Upvotes: 1

Paul Rubel
Paul Rubel

Reputation: 27242

You're allocating 2 characters (say 2 bytes)

char* number = malloc(sizeof(char)*2);
if (c->subtype < 10){

You then fill the first with '0'

    number[0] = '0';

and then try to put two more characters into it. That last null will overflow your allocated storage. At this poing you're on borrowed time and who knows what will happen. If you've corrupted something close uses it may break there.

    sprintf(number+1,"%d\0",c->subtype);
}else{

here too.

    sprintf(number,"%d\0",c->subtype);
}

Try allocating at least 3 chars for the null termination and also using a checked string copy like snprintf, which will always null terminate and won't go off your array.

Always check return codes.

Upvotes: 0

interjay
interjay

Reputation: 110192

fclose itself is most likely fine. The problem is probably that you have undefined behavior elsewhere in your code, which is causing the program to crash later. The crash just happens to occur during the call to fclose. One example I can see of undefined behavior is:

fileName = malloc(sizeof(char)*17);
strcpy(fileName,"res/SEN/  /  .txt");

This writes 18 bytes (including null terminator) into the allocated 17 bytes. There is also a similar buffer overflow when writing into number. And there could of course be other instances of undefined behavior elsewhere in the code, including in functions you haven't shown. One possible way to try finding the problem is to disable sections of code and see if it still crashes.

Upvotes: 2

Related Questions