记录一个标记所有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  |................|
*