在 cpp 中重新定义 new 和 delete 运算符以跟踪内存分配:无法跟踪整个内存块的删除大小
Posted
技术标签:
【中文标题】在 cpp 中重新定义 new 和 delete 运算符以跟踪内存分配:无法跟踪整个内存块的删除大小【英文标题】:redefining new and delete operators in cpp for tracking memory allocations: cannot track size of delete of whole memory blocks 【发布时间】:2021-03-13 20:18:52 【问题描述】:我想在 C++ 中重新定义一些 new 和 delete 操作符,以尝试和跟踪内存分配/释放,类似这样的东西:
#include <iostream>
#include <vector>
void* operator new(std::size_t n)
std::cout << "[Allocate " << n << " bytes]";
void * ptr_out = malloc(n);
std::cout << " at addr " << ptr_out << std::endl;
return ptr_out;
void operator delete(void* p) throw()
std::cout << "[Free 1 byte] at addr " << p << std::endl;
free(p);
void operator delete(void* p, std::size_t nbr_bytes) throw()
std::cout << "[Free " << nbr_bytes << " bytes] at addr " << p << std::endl;
free(p);
int main()
std::cout << "small vector" << std::endl;
std::vector<int> vec_1 1, 2, 3, 4;
我能够很好地拦截内存分配(新),但是我无法以显示整个内存块已释放的方式拦截内存释放(删除),即我得到:
small vector
[Allocate 16 bytes] at addr 0x55b1c5d84280
[Free 1 byte] at addr 0x55b1c5d84280
虽然我真的想表明当程序返回时程序释放了向量的全部 16 个字节。
知道我是否/如何做到这一点,即打印以下内容吗?
small vector
[Allocate 16 bytes] at addr 0x55b1c5d84280
[Free 16 bytes] at addr 0x55b1c5d84280
【问题讨论】:
您需要自己记账,因为无法从void *
获取分配的大小
您可能需要创建一个自定义类,您可以在其中执行上述操作,并在内存中跟踪其内容的确切大小...
实现将大小保持在某处,但它是实现定义的行为。
与msvc相关:https://***.com/questions/4955399/visual-studio-2010-c-get-size-of-memory-block-allocated-by-malloc
https://***.com/questions/852072/simple-c-implementation-to-track-memory-malloc-free 这个答案建议使用一个库来为您进行跟踪:https://***.com/a/852532/487892
【参考方案1】:
当删除不完整类型的对象以及非类和可简单破坏的类类型(ref1、ref2)的数组时,将调用哪些 operator delete
重载由实现定义。
Vector 可能正在分配 char
s 或类似的,因此您必须遵守此规则。
您可以使用nbr_bytes
参数来提高效率如果你得到它,但如果你想保证访问,你必须自己存储信息给它。
如果您使用std::map
这样做,请注意不要将自己写成递归灾难?。
【讨论】:
好的,所以你的意思是调用哪个删除操作符是特定于实现的,对吧?但是,我不明白如何在 addr 0x55b1c5d84280 处打印出 [Free 1 byte] 消息;这意味着我重新定义的删除运算符已被以某种方式调用。 @Zorglub29 是的,但你的第一个,而不是你的第二个。你不能依赖第二个被调用。 好的,谢谢,我想我明白了。问题是,在我的范围之外,有一些关于存储块的元数据,对吧? :) 。这听起来有点棘手。 嗯,是的,也不是。从这些运算符的角度来看,不,除了operator new
的参数之外,任何地方都不存在这样的元数据,这完全是重点:它不存在因为您没有将其存储以供以后使用采用。但是,由于您将实际分配委托给malloc
和free
,我们可以讨论那些 东西可能存储的数据类型,在典型平台上答案变为“是”只要您确实委派了这些分配功能。以上是关于在 cpp 中重新定义 new 和 delete 运算符以跟踪内存分配:无法跟踪整个内存块的删除大小的主要内容,如果未能解决你的问题,请参考以下文章