【问题标题】:How to find out if a memory of a pointer is already deallocated?如何找出指针的内存是否已被释放?
【发布时间】:2021-06-19 05:40:33
【问题描述】:

我试图找出分配的总内存,然后由我的程序释放,以通过重载 new 和 delete 运算符来确定是否存在任何内存泄漏。下面是new和delete的重载方法:

void* operator new(size_t sz)
{
    void* m = (void*) MemoryManager::getInstance()->allocate(sz, false);
    if(!m){
        throw std::bad_alloc{};
    }
    return m;
}

// Overloading Global delete operator
void operator delete(void* m) noexcept
{
    MemoryManager::getInstance()->deallocate(m, false);
}

new 和 delete 调用的 allocate 和 deallocate 方法定义如下:

PointerType allocate(size_t size, bool isArray){
    PointerType newPtr = (PointerType)std::malloc(size);
    mMemKeeper[newPtr] = size;
    mBytes += size;
    return newPtr;
}

void  MemoryManager::deallocate(void* pt, bool isArray){
    LockGuard lck(mGateKeeper);
    if(mMemKeeper.find((PointerType)pt) != mMemKeeper.end()){
        mBytes -= mMemKeeper[(PointerType)pt];
        mMemKeeper.erase((PointerType)pt);
        std::free(pt);
    }
}

typedef char*                                                 PointerType;
typedef std::unordered_map<PointerType, MemoryInfo,
std::hash<PointerType>, std::equal_to<PointerType>,
my_allocator<std::pair<const PointerType, MemoryInfo> > >     OrderedMap;
OrderedMap                                                    mMemKeeper;

我面临的问题是在访问mMemKeeper.find((PointerType)pt) 时解除分配。似乎指针pt 在到达此处时已经被释放,并且取消引用它会导致问题。什么时候会发生这种情况?有什么方法可以检测pt 的内存是否已被释放?

【问题讨论】:

  • 当 Visual Studio 发生此问题时,我尝试访问指针的内存位置,它显示 00 00 00 00 00 00,我认为这意味着内存已被释放
  • 我认为这意味着内存已被释放没有 Visual Studio 有不同的代码。相关:https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations
  • 考虑不要这样做,除非你这样做是为了运动/娱乐/学习。已经有多种专门的工具用于检测内存泄漏
  • 你能提供一个minimal reproducible example吗?此外,您的deallocate 函数正在搜索地图三次! 1.mMemKeeper.find(...) 2.mMemKeeper[...] 3.mMemKeeper.erase(...).改为 1.auto it = mMemKeeper.find(...) 2.it-&gt;second 3.mMemKeeper.erase(it)
  • 您总是可以在缓冲区前后分配一个额外的空间,并在其中放入一个幻数,这对于检测溢出也很有用。

标签: c++ malloc new-operator free delete-operator


【解决方案1】:

似乎指针 pt 在到达此处时已被释放,并且取消引用它会导致问题。

是的,双重释放是一个错误。访问 free'd 内存的结果是不确定的。

当此问题从 Visual Studio 发生时,我尝试访问指针的内存位置,它显示 00 00 00 00 00 00,我认为这意味着内存已被释放

如果您在指针可能未分配时取消引用,那么您已经失败了。确定指针是否已分配的唯一安全方法是在别处查找。

什么时候会发生这种情况

当你多次显式地delete 同一个对象,或者当你显式地delete 某个已经由智能指针控制的东西,或者如果你显式地delete 某个没有在new 中分配的东西时第一名。

有没有一种方法可以检测 pt 的内存是否已被释放?

你有点已经是了。如果地址不在您的已分配块容器中,则它要么一开始就没有从这里分配,要么已经被释放。如果需要,您可以为双重释放添加一些显式跟踪:只需添加另一个容器。

我试图找出分配的总内存,然后由我的程序释放,以确定是否有任何内存泄漏

如果这只是为了您自己的兴趣/学习,那很好。否则你会错过很多功能,如果有的话,你应该只使用编译器的地址清理器,如果没有的话,应该使用 valgrind。

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 2011-11-15
    • 2012-12-28
    • 2012-01-08
    • 2022-09-27
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多