Here is what I use:
In new.cpp
const char* __file__ = "unknown";
size_t __line__ = 0;
void* operator new(size_t size) {
void *ptr = malloc(size);
record_alloc(ptr,__file__,__line__);
__file__ = "unknown";
__line__ = 0;
return ptr;
}
void delete(void *ptr)
{
unrecord_alloc(ptr);
free(ptr);
}
For compactness, I'm leaving out the other definitions of new and delete. "record_alloc" and "unrecord_alloc" are functions that maintain a linked list of structure containing ptr, line, and file).
in new.hpp
extern const char* __file__;
extern size_t __line__;
#define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new
For g++, "new" is expanded only once. The key is the "&& 0" which makes it false and causes the real new to be used. For example,
char *str = new char[100];
is expanded by the preprocessor to
char *str = (__file__="somefile.c",__line__=some_number) && 0 ? NULL : new char [100];
Thus file and line number are recorded and your custom new function is called.
This works for any form of new -- as long as there is a corresponding form in new.cpp
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…