c++ - fclose() 的 free()/delete/delete[]/realloc() 无效?

标签 c++ linux free delete-operator

我尝试在 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/

相关文章:

c++ - 为什么共享指针不删除内存?

php - 不同的 PHP 目录 Apache + CLI (chrooted)

c++ - 可以读取 'select' 调用保持查找客户端套接字

c - 释放引用还是释放指针?我们能判断一个参数是引用还是指针吗?

c - 释放内存函数 C

c++ - C++ 如何处理这个

c++ - 在 C 和 C++ 中 main() 应该返回什么?

linux - 优化基于MAC地址匹配提取子串的bash脚本

c - 如何释放另一个链表中的链表?

c++ - 为什么我的节点在使用 free() 或 delete 时没有被删除