如何确定指针的内存是否已经解除分配?

How to find out if a memory of a pointer is already deallocated?

提问人:Bharath 提问时间:3/22/2021 最后编辑:Jarod42Bharath 更新时间:3/22/2021 访问量:292

问:

我正在尝试找出我的程序分配和稍后释放的总内存,以确定是否存在任何内存泄漏,因为重载了 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 和 relocate 方法定义如下:

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)ptpt

C++ malloc new-operator 免费 删除运算符

评论

0赞 Bharath 3/22/2021
当Visual Studio发生此问题时,我尝试访问指针的内存位置,它显示00 00 00 00 00 00 00 00,我认为这意味着内存已经释放
0赞 drescherjm 3/22/2021
我假设意味着内存已经释放没有 Visual Studio 为此提供不同的代码。相关新闻: https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations
6赞 bartop 3/22/2021
考虑不要这样做,除非你这样做是为了运动/娱乐/学习。已经有多种专门用于检测内存泄漏的工具
1赞 Kevin 3/22/2021
你能提供一个最小的可重复的例子吗?此外,您的函数正在搜索地图三次!1. 2. 3. .执行类似 1 的操作。 2. 3. 相反。deallocatemMemKeeper.find(...)mMemKeeper[...]mMemKeeper.erase(...)auto it = mMemKeeper.find(...)it->secondmMemKeeper.erase(it)
1赞 doug 3/22/2021
您始终可以在缓冲区之前和之后分配一个额外的空间,并在其中放置一个幻数 对于检测溢出也很有用。

答:

0赞 Useless 3/22/2021 #1

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

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

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

如果在指针可能未分配时取消引用指针,则说明已失败。确定指针是否分配的唯一安全方法是在其他地方查找它。

什么时候会发生这种情况

当您多次显式使用同一对象时,或者当您显式已由智能指针控制的内容时,或者如果您显式了最初未分配的内容。deletedeletedeletenew

有没有办法检测 pt 的内存是否已经释放?

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

我正在尝试找出我的程序分配并随后释放的总内存,以确定是否存在任何内存泄漏

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