批评我的堆调试器
我写了下面的堆调试器来演示内存泄漏,双重删除和错误形式的删除(即试图删除一个delete p
而不是delete[]
p)到开始的程序员。
我很想从强大的C ++程序员那里得到一些反馈,因为我从来没有这样做过,我确信我犯了一些愚蠢的错误。 谢谢!
#include <cstdlib>
#include <iostream>
#include <new>
namespace
{
const int ALIGNMENT = 16;
const char* const ERR = "*** ERROR: ";
int counter = 0;
struct heap_debugger
{
heap_debugger()
{
std::cerr << "*** heap debugger startedn";
}
~heap_debugger()
{
std::cerr << "*** heap debugger shutting downn";
if (counter > 0)
{
std::cerr << ERR << "failed to release memory " << counter << " timesn";
}
else if (counter < 0)
{
std::cerr << ERR << (-counter) << " double deletes detectedn";
}
}
} instance;
void* allocate(size_t size, const char* kind_of_memory, size_t token) throw (std::bad_alloc)
{
void* raw = malloc(size + ALIGNMENT);
if (raw == 0) throw std::bad_alloc();
*static_cast<size_t*>(raw) = token;
void* payload = static_cast<char*>(raw) + ALIGNMENT;
++counter;
std::cerr << "*** allocated " << kind_of_memory << " at " << payload << " (" << size << " bytes)n";
return payload;
}
void release(void* payload, const char* kind_of_memory, size_t correct_token, size_t wrong_token) throw ()
{
if (payload == 0) return;
std::cerr << "*** releasing " << kind_of_memory << " at " << payload << 'n';
--counter;
void* raw = static_cast<char*>(payload) - ALIGNMENT;
size_t* token = static_cast<size_t*>(raw);
if (*token == correct_token)
{
*token = 0xDEADBEEF;
free(raw);
}
else if (*token == wrong_token)
{
*token = 0x177E6A7;
std::cerr << ERR << "wrong form of deleten";
}
else
{
std::cerr << ERR << "double deleten";
}
}
}
void* operator new(size_t size) throw (std::bad_alloc)
{
return allocate(size, "non-array memory", 0x5AFE6A8D);
}
void* operator new[](size_t size) throw (std::bad_alloc)
{
return allocate(size, " array memory", 0x5AFE6A8E);
}
void operator delete(void* payload) throw ()
{
release(payload, "non-array memory", 0x5AFE6A8D, 0x5AFE6A8E);
}
void operator delete[](void* payload) throw ()
{
release(payload, " array memory", 0x5AFE6A8E, 0x5AFE6A8D);
}
而不是干扰笔记,你可以保留所有分配清单。 然后,您可以释放内存而不破坏自己的数据,并记录特定地址被“删除”的次数,还可以找到程序试图删除不匹配地址(即不在列表中)的地方。
这是一个非常好的开始。 这是我的2美分,因为你已经要求反馈:
解释为什么选择“ALIGNMENT”作为标识符。 解释你为什么选择了16.争论你的算法如何捕获最常见的错误,如溢出堆分配块的末尾或忘记释放内存。
链接地址: http://www.djcxy.com/p/73019.html上一篇: Critique my heap debugger
下一篇: How should I write ISO C++ Standard conformant custom new and delete operators?