Click here to Skip to main content
15,909,440 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have overloaded new which calls a Trackmemory::heapinfo() this class Trackmemory is defined in the header file and the functionis defined in the other file. I have defined macros in the same header file..

Defined in the header :
C++
#ifndef __MEMORY_LEAK_CODE__
#define new DEBUG_NEW
#define DEBUG_NEW TrackMemory(__FILE__, __LINE__) ->* new
#endif 

Class is somewhat like this.
C++
class TrackMemory
{
    private:
        const char* fileName;
        const int   lineNumber;
        TrackMemory(const TrackMemory&);
        TrackMemory& operator=(const TrackMemory&);
        void ModifyHeapInfo(void* pointer);
    public:
        TrackMemory(const char* file, int line): fileName(file), lineNumber(line) {}
        template <class _Tp> _Tp* operator->*(_Tp* pointer)
        {
            ModifyHeapInfo(pointer); return pointer;
        }
};


When the allocation is made using new..everything works fine trackmemory is expanded heapinfo() is called and everything required is stored...But when any of the STL containers call new implicitly call is directed to the overloaded new and trackmemory is not expanded and the heapinfo() is also not called ...Can anyone help in overcoming this problem. Please let me know if you need to take a look at anything else to resolve the issue.
Posted
Comments
JackDingler 28-Feb-12 11:41am    
Is there a reason you want to track memory in the STL? It has a good track record in memory management, as it's a very mature technology.

Most detected leaks that occur as a side effect of STL behavior tend to come from not closing globals and statics in ExitInstance()

Your includes for the STL containers, likely occur before your macro is declared. So they get the default new().


C++
#include <vector>

#ifndef __MEMORY_LEAK_CODE__
#define new DEBUG_NEW
#define DEBUG_NEW TrackMemory(__FILE__, __LINE__) ->* new
#endif 


versus

C++
#ifndef __MEMORY_LEAK_CODE__
#define new DEBUG_NEW
#define DEBUG_NEW TrackMemory(__FILE__, __LINE__) ->* new
#endif 

#include <vector>
 
Share this answer
 
v3
I don't think you can do that.

If you were to put your #defines at the top of the first file hit by the compiler (i.e. above any include statements) you should get a new global new. But doing that would just lead to other problems, most likely compilation problems.

Think about it; the way you've redefined new is applicable for allocating and only allocating, but new is used for more stuff.
Typically the STL will in some cases use custom new implementations by overloading operator new;
C++
void* operator new[](size_t _Size)
{
 // Some implementation of allocation
}


And in such a scenario, where new is part of method declaration rather than an allocation statement, your #define will yield a compilation error.

Hope this helps,
Fredrik
 
Share this answer
 
Comments
JackDingler 28-Feb-12 11:37am    
That's right Fredrik, it's not a good idea to do this. It turns into a maintenance headache. It mostly works, most of the time...

I posted it that way, to illustrate why his approach didn't work.
Member 8576081 1-Mar-12 5:18am    
Thank you for your valuable suggestions.
@JackDingler - STL containers are not calling the default new .They are calling the overloaded ones only but comes out of it without calling heapinfo() which is called in other cases when 'new' is used explicitly by the user. I dont understand why is it happening..

@Fredrik Bornander - You are absolutely right but I have overloaded new[] as well..As i told you earlier everything is working perfectly except for this little thing.
Let me explain the whole thing in detail.
Whenever some STL container calls the overloaded new ,it comes out of it without calling the TrackMemory::heapinfo(stores the pointer to the allocated memory in stack) due to which the stack is not updated with the required information . Whenever the corresponding ‘delete’ is called by the STL container via erase, my code fails to find the pointer to the allocated memory location which needs to be deleted in the stack ,as it was never updated in the stack and it causes my code to show a false memory leak. Therefore if I could somehow ensure that every call to new leads to the calling of Trackmemory::HeapInfo() , the problem will be solved.
Thank you for your valuable suggestions.
@JackDingler - STL containers are not calling the default new .They are calling the overloaded ones only but comes out of it without calling heapinfo() which is called in other cases when 'new' is used explicitly by the user. I dont understand why is it happening..

@Fredrik Bornander - You are absolutely right but I have overloaded new[] as well..As i told you earlier everything is working perfectly except for this little thing.
Let me explain the whole thing in detail.
Whenever some STL container calls the overloaded new ,it comes out of it without calling the TrackMemory::heapinfo(stores the pointer to the allocated memory in stack) due to which the stack is not updated with the required information . Whenever the corresponding ‘delete’ is called by the STL container via erase, my code fails to find the pointer to the allocated memory location which needs to be deleted in the stack ,as it was never updated in the stack and it causes my code to show a false memory leak. Therefore if I could somehow ensure that every call to new leads to the calling of Trackmemory::HeapInfo() , the problem will be solved.
 
Share this answer
 
Comments
Member 8576081 1-Mar-12 0:39am    
Any suggestions?
any suggestions ? How can I solve this problem?
 
Share this answer
 
Comments
Stefan_Lang 1-Mar-12 3:55am    
You can start by possting your responses as a comment to the appropriate solution rather than as a new 'solution'! Those two people who ofered you possible solutions will get no notification of your responses this way! By posting a comment to a solution however, like what I'm doing now, they will get an email notification.
Member 8576081 1-Mar-12 5:18am    
ok! thanks for the info !:)
STL containers do not allocate memory by calling new on the appropriate element types. Instead they allocate memory blocks of arbitrary size, and then call placement new on blocks within that already allocated memory. It works something like this:
C++
if (required_element_number > reserved_element_number) {
   size_t new_element_number = determine_new_reserved_size(required_element_number);
   size_t allocated = allocator->alloc(new_element_number*size_of(element_type);
   for (/*each old element*/) {
      // copy old element to new location using copy constructor and in-place new
      new(/*pointer_to_new_location*/) element_type(/*old_element*/);
   }
   for (/*each new required element*/) {
      // construct new elements using default constructor and placement new
      new(/*pointer_to_memory_location*/) element_type;
   }
}

note that allocator is a template argument that can be passed as an optional argument. I believe the default is calling new on type char, so you may get unexpected calls to new char, rather than calls to new for the element type you actually have. Also note that the in-place calls to new that call the constructors do not assign the result of the new operator and therefore may not fit into the scheme you provided. Also, the two uses of placement new involve both the copy and default constructor of your element type.
 
Share this answer
 
Comments
Member 8576081 2-Mar-12 0:20am    
Ok..I got your point..Can you suggest what can be done to solve this problem with minimal change in the code.
Stefan_Lang 2-Mar-12 4:01am    
Unfortunately there isn't much more I can tell you as I never tried to program a leak detector or similar myself. I do know however, that what you are trying to accomplish is already included in the AFX library provided with MS Visual Studio. afx.h, among other things, contains the following declarations:

#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)

// Memory tracking allocation
void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
#define DEBUG_NEW new(THIS_FILE, __LINE__)
void AFX_CDECL operator delete(void* p, LPCSTR lpszFileName, int nLine);

void * __cdecl operator new[](size_t);
void* __cdecl operator new[](size_t nSize, LPCSTR lpszFileName, int nLine);
void __cdecl operator delete[](void* p, LPCSTR lpszFileName, int nLine);
void __cdecl operator delete[](void *);

As you can see, they provided no less than three polymorphic operators new to override the default behaviour, and three operators delete as well. If you have and use the AFX library you can just switch this on by defining the preprocessor symbol _DEBUG, otherwise I presume you will have to find out how to implement these overrides yourself.
Member 8576081 5-Mar-12 0:43am    
Ok . Thanks!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900