记录一个标记所有new出来的内存的地址加上TAG
#pragma once #include <iostream> #include <cstring> #include <cstdlib> #include <new> #include <typeinfo> // 可选,如果不想用宏自动传名可以结合 typeid // 只在调试模式下启用 #ifdef _DEBUG struct MemHeader { char className[128]; // 存储类名 size_t size; // 用户请求的字节数 // 可以添加:file, line, timestamp 等 }; // 带类名参数的 operator new inline void* operator new(size_t sz, const char* name) { size_t total = sizeof(MemHeader) + sz; void* raw = malloc(total); if (!raw) throw std::bad_alloc(); MemHeader* h = static_cast<MemHeader*>(raw); // 安全复制类名,截断超过 127 个字符 strncpy(h->className, name, sizeof(h->className) - 1); h->className[sizeof(h->className) - 1] = '\0'; h->size = sz; // 返回用户区域指针(头部之后) return static_cast<char*>(raw) + sizeof(MemHeader); } // 对应的 operator delete(释放时回退头部) inline void operator delete(void* p) noexcept { if (!p) return; void* raw = static_cast<char*>(p) - sizeof(MemHeader); free(raw); } // 为了安全,也重载 placement delete(如果构造函数抛出异常会调用) inline void operator delete(void* p, const char*) noexcept { ::operator delete(p); } // --- 宏定义(自动传入类名)--- // 用法:NEW(MyClass) → 调用默认构造 // NEW(MyClass, arg1) → 调用带参构造 #define NEW(T, ...) new (#T) T(__VA_ARGS__) #else // 非调试模式,直接使用标准 new #define NEW(T, ...) new T(__VA_ARGS__) #endif

main.cpp

#include "debug_new.h" #include <iostream> #include <unistd.h> class MyClass { public: MyClass() { std::cout << "MyClass default constructed" << std::endl; } MyClass(int x) { std::cout << "MyClass constructed with " << x << std::endl; } ~MyClass() { std::cout << "MyClass destroyed" << std::endl; } }; class Another { int a; public: Another(int a, double b) : a(a) { std::cout << "Another(" << a << ", " << b << ")" << std::endl; } }; int main() { // 使用 NEW 宏,自动传入类名 MyClass* obj1 = NEW(MyClass); MyClass* obj2 = NEW(MyClass, 42); Another* obj3 = NEW(Another, 10, 3.14); while(1) sleep(1); delete obj1; delete obj2; delete obj3; return 0; }

armg++ -D_DEBUG -g -o myapp main.cpp -std=c++11

Breakpoint 2, MyClass::MyClass (this=0x424ca8) at main.cpp:7 7 in main.cpp (gdb) bt #0 MyClass::MyClass (this=0x424ca8) at main.cpp:7 #1 0x0000000000400e4c in main () at main.cpp:20

dump

(gdb) p (char*)0x424ca8 - 136 $2 = 0x424c20 "MyClass" (gdb) dump memory /data/pub/d.bin 0x424ca8 0x445000 (gdb) dump memory /data/pub/d.bin 0x424ca8-136 0x445000
root@hovfree:/data/pub# hexdump -C d.bin 00000000 4d 79 43 6c 61 73 73 00 00 00 00 00 00 00 00 00 |MyClass.........| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| *