我尝试在 Linux64 上运行/编译 OpenTibia 服务器。小调整,编译,一切似乎都很好。然而,Valgrind 说:
==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)
现在代码开始了,对于 FileLoader(尤其是析构函数):
/*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 只是 FileLoader 的扩展:
class ItemLoader : public FileLoader {/*Overrides nothing*/};
现在到 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;
}
问题是,Valgrind 是否指向 fclose 或其他问题? 另请注意,该应用程序使用 libboost(如果这有任何关系的话)。 我尽量做到具体
最佳答案
Vagrind 直接向您展示了问题——您在同一 FILE
描述符上调用了 fclose
两次:
==32360== Invalid free() / delete / delete[] / realloc()
==32360== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
second call ==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)
first call ==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)
第二次调用是在第 49 行的析构函数中,第一次是在第 92 行的 openFile 中。
关于c++ - fclose() 的 free()/delete/delete[]/realloc() 无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32541611/