I try to run/compile OpenTibia Server on Linux64. Little tweaks, compiled and everything seemed fine. Yet, Valgrind says:
==32360== Invalid free() / delete / delete[] / realloc()
==32360== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32360== by 0x6074AE4: fclose@@GLIBC_2.2.5 (iofclose.c:85)
==32360== by 0x41CF8D: FileLoader::~FileLoader() (fileloader.cpp:49)
==32360== by 0x45DB1B: Items::loadFromOtb(std::string) (itemloader.h:232)
==32360== by 0x4067D7: main (otserv.cpp:564)
==32360== Address 0x8126590 is 0 bytes inside a block of size 568 free'd
==32360== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32360== by 0x6074AE4: fclose@@GLIBC_2.2.5 (iofclose.c:85)
==32360== by 0x41D268: FileLoader::openFile(char const*, bool, bool) (fileloader.cpp:92)
==32360== by 0x45DB00: Items::loadFromOtb(std::string) (items.cpp:230)
==32360== by 0x4067D7: main (otserv.cpp:564)
Now the code goes, for FileLoader (especially destructor):
/*somewhere in the header*/
FILE* m_file;
FileLoader::FileLoader() {
m_file = NULL;
m_buffer = new unsigned char[1024];
//cache, some cache data
memset(m_cached_data, 0, sizeof(m_cached_data));
}
FileLoader::~FileLoader() {
if(m_file){
fclose(m_file);
m_file = NULL;
}
delete[] m_buffer;
for(int i = 0; i < CACHE_BLOCKS; i++){
if(m_cached_data[i].data)
delete m_cached_data[i].data;
}
}
bool FileLoader::openFile(const char* filename, bool write, bool caching /*= false*/){
if(write) {/*unimportant*/}
else {
unsigned long version;
m_file = fopen(filename, "rb");
if(m_file){
fread(&version, sizeof(unsigned long), 1, m_file);
if(version > 0){/*version is 0*/}
else{
if(caching){
m_use_cache = true;
fseek(m_file, 0, SEEK_END);
int file_size = ftell(m_file);
m_cache_size = min(32768, max(file_size/20, 8192)) & ~0x1FFF;
}
return true;
}
}
else{
m_lastError = ERROR_CAN_NOT_OPEN;
return false;
}
}
}
ItemLoader is just an extension to FileLoader:
class ItemLoader : public FileLoader {/*Overrides nothing*/};
Now to the function in Items:
int Items::loadFromOtb(std::string file) {
ItemLoader f;
if(!f.openFile(file.c_str(), false, true)){return f.getError();}
//...Loading, processing, reading from file and stuff...
//delete &f; //I tried this but didn't change anything
return ERROR_NONE;
}
The question is, does Valgrind point to problem with fclose or rather something else? Also note that the application uses libboost (if this has anything to do). I tried to be as specific as possible