2024/8/7大约 2 分钟

CppUpgrade
仓库地址
为了方便说明,对int进行简单封装,其定义如下:
class Int {
public:
	int value;
};本文实现内存统计的思路是:
 在每次申请内存时,在真正所需内存的开头额外申请一块内存,存储当前内存块的信息,如大小、类型等。
 对应的,在内存释放时需要同时释放额外申请的内存。
0.传统new的执行过程
  new Int()
  |
  |-operator new()
  | |
  | --malloc()
  |
  --Int()1.对底层内存分配、内存释放函数进行封装
namespace qstx {
  static std::atomic<size_t> total_memory = 0;
  struct header
  {
    size_t size = 0;
    const char* type = nullptr;
  };
  void* m_malloc(size_t size, const char* type)
  {
    void* header_ptr = malloc(sizeof(header) + size);
    header* tmp_header = static_cast<header*>(header_ptr);
    tmp_header->size = size;
    tmp_header->type = type;
    total_memory += size;
    return (unsigned char*)header_ptr + sizeof(header);
  }
  void m_free(void* ptr)
  {
    void* header_ptr = (unsigned char*)ptr - sizeof(header);
    total_memory -= static_cast<header*>(header_ptr)->size;
    free(header_ptr);
  }
}2.重写类的new、delete函数
static void* operator new(size_t size)
{
	return qstx::m_malloc(size, typeid(Int).name());
}
static void* operator new[](size_t size)
{
	return qstx::m_malloc(size, typeid(Int).name());
}
static void operator delete(void* ptr)
{
	qstx::m_free(ptr);
}
static void operator delete[](void* ptr)
{
	qstx::m_free(ptr);
}3.验证
通过new、delete构造和销毁对象,输出使用的总内存进行验证
int main()
{
	{
		Int* p = new Int();
		std::cout << "Int value: " << p->value << std::endl;
		std::cout << "Memory Used: " << qstx::total_memory << "Bytes" << std::endl;
		delete p;
	}
	std::cout << "Memory Used: " << qstx::total_memory << "Bytes" << std::endl;
	std::cout << std::endl;
	{
		Int* p_array = new Int[3];
		for (int i = 0; i < 3; ++i) {
			p_array[i].value = i;
			std::cout << "Int value: " << p_array[i].value << std::endl;
			std::cout << "Memory Used: " << qstx::total_memory << "Bytes" << std::endl;
		}
		delete[] p_array;
	}
	std::cout << "Memory Used: " << qstx::total_memory << "Bytes" << std::endl;
}上述代码的输出如下:
Int value: 0
Memory Used: 4Bytes
Memory Used: 0Bytes
Int value: 0
Memory Used: 12Bytes
Int value: 1
Memory Used: 12Bytes
Int value: 2
Memory Used: 12Bytes
Memory Used: 0Bytes4.改进
直接定义一个宏,在类中批量重载new、delete函数
#define	DEFINE_CLASS_MEMORY_ALLOCATOR(type)               \
	static void* operator new(size_t size) {              \
		return qstx::m_malloc(size, typeid(type).name()); \
	}                                                     \
	static void* operator new[](size_t size) {            \
		return qstx::m_malloc(size, typeid(type).name()); \
	}                                                     \
	static void operator delete(void* ptr) {              \
		qstx::m_free(ptr);                                \
	}                                                     \
	static void operator delete[](void* ptr) {            \
		qstx::m_free(ptr);                                \
	}
class Int {
public:
	DEFINE_CLASS_MEMORY_ALLOCATOR(Int)
	//Other Codes
};