I'm writing a big application and i recently included there my new module for working with files. It has simple functions of writing integers and strings, it was tested to be perfect on Red Hat. It does exactly what i want.
Here's the implementation of the functions there:
int CFile_open(CFile* owner, char* filename, char* mode) {
owner->file = fopen(filename, mode);
if (owner->file == NULL) {
return 0;
} else {
return 1;
}
}
int CFile_close(CFile* owner) {
if (owner->file == NULL) {
return 0;
} else {
if (fclose(owner->file) ) {
return 1;
} else {
return 0;
}
}
}
int CFile_writeInt(CFile* owner, int num) {
if (owner->file == NULL) {
return 0;
} else {
if (fwrite(&num, sizeof(int), 1, owner->file)) {
return 1;
} else {
return 0;
}
}
}
int CFile_writeString(CFile* owner, char* str) {
if (owner->file == NULL) {
return 0;
} else {
char b = strlen(str);
if (fwrite(&b, sizeof(char), 1, owner->file)) {
for (int i=0; i<=b; i++) {
fwrite(&str[i], sizeof(char), 1, owner->file);
}
} else {
return 0;
}
}
}
These functions are being used in the wrapper-function and then being executed in my application.
Here's that function:
void fileWrite(void* data) {
CList* list = (CList*)data;
CNode* node = list->first;
CData* info = NULL;
CFile* f = (CFile*)malloc(sizeof(CFile));
f->init = CFile_init;
f->init(f);
if (list->length == 0) {
printf("%s\n", "The list is empty!");
wait();
} else {
int i = 1;
if (f->open(f, (char*)"./f", (char*)"w")) {
while (node) {
info = node->getData(node);
if (f->writeInt(f, info->getNum(info))) {
if (f->writeString(f, info->getAdr(info))) {
if (f->writeString(f, info->getPh(info))) {
printf("%s%d\n", "Wrote item #", i);
i++;
} else {
printf("%s%d\n", "Error writing Phone of item #", i);
}
} else {
printf("%s%d\n", "Error writing Adress of item #", i);
}
} else {
printf("%s%d\n", "Error writing Number of item #", i);
}
node = node->next;
}
if (f->close(f)) {
printf("%s\n", "Wrote successfully");
wait();
}
}
free(f);
}
}
The problematic spot is the f->close(f)
at the very end of the function.
If i don't close the file, everything works flawlessly. But if i do, i'm getting the following error:
*** Error in 'a.out': free(): invalid next size (normal): 0x0859c320 ***
However, despite the application crash, it does close the file, and the info i wrote to it is correct and not corrupted.
But i can't figure out why am i getting the error. I close the file only once (as you may see from the function), and i also tried commenting the free(f)
line.
Also if i call fclose(f->file)
there i get the same error, so that's not the close()
function issue.
I assume that the rest of the application works (and worked before i added the function) perfectly except for the line where i close the file.
The reason i mentioned RedHat is because it was working perfectly there, but when i recompiled it under ArchLinux (also tried Debian) - it won't close the file. Same compiler versions were used everywhere.
I compile it with g++
if that matters, but i also have the same issue with clang++
.
I also tried running it with valgrind
and it says nothing about files, or i just couldn't find the right keys for that. Perhaps you know?
So do you have any ideas on what's going on and how to fix it? I was staring at the code for literally 3 hours already and i can't figure it out for the life of me.
Test case:
info->getNum()
returns integer "11" (assigned during input)
info->getAdr()
returns dynamically allocated char array "aa" (allocated and assigned during input)
info->getPh()
returns dynamically allocated char array "bb" (allocated and assigned during input)
I can test these values using other functions in my application, so i'm 100% confident they are correct.
Then i just evoke the fileWrite()
function.