пишу, хотя это не совсем корректно называть каноничным переопределением new\delete

void AddPointer(void * pointer, const char * fileName, unsigned int lineNum, unsigned char type, unsigned int size);
void RemovePointer(void * pointer, const char * fileName, u32 lineNum, u8 type);
void * Allocate(size_t size);
void * ReAllocate(void * pointer, size_t size);
void Free(void * pointer);
#define MM_NEW(__var, __obj) \
{ \
__var = new __obj; \
AddPointer(__var, __FILE__, __LINE__, 0, sizeof(__obj)); \
}
#define MM_NEW_S(__obj) \
{ \
void * __ptr = new __obj; \
AddPointer(__ptr, __FILE__, __LINE__, 0, sizeof(__obj)); \
}
#define MM_DELETE(__var) \
{ \
RemovePointer(__var, __FILE__, __LINE__, 0); \
delete(__var); \
}
#define MM_NEW_A(__var, __obj, __count) \
{ \
__var = new __obj [__count]; \
AddPointer(__var, __FILE__, __LINE__, 1, sizeof(__obj) * __count); \
}
#define MM_NEW_S_A(__obj, __count) \
{ \
void * __ptr = new __obj [__count]; \
AddPointer(__ptr, __FILE__, __LINE__, 1, sizeof(__obj) * __count); \
}
#define MM_DELEMM_A(__var) \
{ \
RemovePointer(__var, __FILE__, __LINE__, 1); \
delete [] (__var); \
}
#define MM_NEW_P(__var, __ptr, __obj) \
{ \
__var = new (__ptr) __obj; \
AddPointer(__ptr, __FILE__, __LINE__, 2, sizeof(__obj)); \
}
#define MM_NEW_S_P(__ptr, __obj) \
{ \
new (__ptr) __obj; \
AddPointer(__ptr, __FILE__, __LINE__, 2, sizeof(__obj)); \
}
#define MM_DELEMM_P(__var, __destructor_name) \
{ \
(__var)->__destructor_name; \
RemovePointer(__var, __FILE__, __LINE__, 2); \
}
как плюс :
1) нету проблем с сторонними либами, потому что либа может содержать в хидерах вызов new\delete и поставляться в уже собранном виде, а мы при подключении хидера переопределим new\delete и всё сломается
2) в дебаге мы следим за каждым выделением, потому если что-то потечет то сразу узнаем где