#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 |................|
*