提问人:Bharath 提问时间:3/22/2021 最后编辑:Jarod42Bharath 更新时间:3/22/2021 访问量:292
如何确定指针的内存是否已经解除分配?
How to find out if a memory of a pointer is already deallocated?
问:
我正在尝试找出我的程序分配和稍后释放的总内存,以确定是否存在任何内存泄漏,因为重载了 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)
pt
pt
答:
似乎指针 pt 到达此处时已经释放,并且取消引用它会导致问题。
是的,双重释放是一个错误。访问可用内存的结果是不确定的。
当Visual Studio发生此问题时,我尝试访问指针的内存位置,它显示00 00 00 00 00 00 00 00,我认为这意味着内存已经释放
如果在指针可能未分配时取消引用指针,则说明已失败。确定指针是否分配的唯一安全方法是在其他地方查找它。
什么时候会发生这种情况
当您多次显式使用同一对象时,或者当您显式已由智能指针控制的内容时,或者如果您显式了最初未分配的内容。delete
delete
delete
new
有没有办法检测 pt 的内存是否已经释放?
你已经是了。如果该地址不在已分配块的容器中,则它要么一开始就没有从这里分配,要么已经被释放。如果需要,可以添加一些用于双重释放的显式跟踪:只需添加另一个容器即可。
我正在尝试找出我的程序分配并随后释放的总内存,以确定是否存在任何内存泄漏
如果这只是为了你自己的兴趣/学习,那很好。否则,您将错过很多功能,如果编译器有地址清理器,则应使用该地址清理器,如果没有,则应使用valgrind。
评论
deallocate
mMemKeeper.find(...)
mMemKeeper[...]
mMemKeeper.erase(...)
auto it = mMemKeeper.find(...)
it->second
mMemKeeper.erase(it)