I am working on a small memory tool that tracks allocations and releases, object sizes, object types, etc. The method that I use to track source files, line numbers, and object types works as follows:
#define DEBUG_NEW SourcePacket(__FILE__, __LINE__) * new #define new DEBUG_NEW
SourcePacket is just a small class that accepts const char * and int at build time. These values ββare populated with the __FILE__ and __LINE__ . The type of object is acquired as follows:
template<typename T> T* operator*(const SourcePacket& packet, T* p);
p - pointer to a newly selected object whose type was detected using RTTI. In operator overloading, information is taken and stored in the tracer, and the pointer is passed to the program. Additional information, such as size and address, is captured in the overloaded new operator.
Now this setup worked very well for me. This does not work for code that I am not compiling, of course, but one of the best things is that it does a great job of posting new calls made by the user that do not work using the often quoted
#define new new(__FILE__, __LINE__)
method. The problem I ran into is that if the user calls the new operator, the program simply cannot compile. Of course, this is because the macro expands so much.
return operator SourcePacket("blahblah.cpp", 20) * new(size);
instead
return SourcePacket("blahblah.cpp", 20) * new(size);
I do not see anything like it. I could, of course, just delete the new SourcePacket * procedure and just let my overloaded operator collect the size and address, but this view affects a significant part of the purpose of the tool.
(Also, as a note, I am not trying to create Valgrind or anything else, and I know that overloading global ops can be pretty tricky. This is mainly for educational purposes. In addition, I know that OS- in order to to detect some of this information, you can use certain functions, but I would like to use only standard C ++ so that it is cross-platform and bit-independent (x86, x64, etc.). Until now, it has worked flawlessly for me on both Linux and Windows, releases of both bit tastes.)
Unfortunately, there is no way to conditionally use one way or another, depending on whether it is just a new (or new or new) or new operator. It is not critical that I get this to work, but I would be interested to hear if anyone has found a way to this restriction.