gpt4 book ai didi

c++ - 批评我的堆调试器

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:09:03 27 4
gpt4 key购买 nike

我编写了以下堆调试器以演示内存泄漏、双重删除和错误的删除形式(即尝试使用 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 started\n";
}

~heap_debugger()
{
std::cerr << "*** heap debugger shutting down\n";
if (counter > 0)
{
std::cerr << ERR << "failed to release memory " << counter << " times\n";
}
else if (counter < 0)
{
std::cerr << ERR << (-counter) << " double deletes detected\n";
}
}
} 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 delete\n";
}
else
{
std::cerr << ERR << "double delete\n";
}
}
}

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);
}

最佳答案

您可以保留所有分配的列表,而不是进行侵入性的记录。然后你可以释放内存而不破坏你自己的数据,并跟踪特定地址被“删除”的次数,还可以找到程序试图删除不匹配地址的地方(即不在列表中)。

关于c++ - 批评我的堆调试器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2830272/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com