views:

106

answers:

2

Unhandled exception at 0x00423e3b in memory_manager.exe: 0xC0000005: Access violation reading location 0x00000004.

Souce file Download: http://www.cppblog.com/Files/mymsdn/memory_manager_bug_vs2008_debug.zip Hey,

I am trying create a memory manager function to resolve some problem:

  1. reference count the new / delete counter when allocate memory to anaylize the memory leak problem.
  2. reduce the memory fragment.

I have writen the memory_manager class to manage allocate and deallocate a block of memory. interface:

void *allocate(size_t size); 
BOOL deallocate(void * ptr); 
// ... 

I am trying to create a placement new to replace the new from the system, so I add the code below to do this.

#ifdef _DEBUG 


static memory_manager mm; 


inline void * __cdecl operator new(unsigned int size, 
                                   const char *file, int line) 
{ 
    void * res; 
    if((res = mm.allocate(size)) == 0) 
    { 
        // go to default allocator 
    } 
    return res; 
}; 


inline void __cdecl operator delete(void *p) 
{ 
    if(!mm.deallocate(p)) 
        return; 
}; 


inline void __cdecl operator delete[]( void * p ) 
{ 
    if(!mm.deallocate(p)) 
        return; 
}; 
#endif 


#ifdef _DEBUG 
#define DEBUG_NEW new(__FILE__, __LINE__) 
#else 
#define DEBUG_NEW new 
#endif 
#define new DEBUG_NEW 

But I encountered the exception in runtime, "Unhandled exception at 0x00423e3b in memory_manager.exe: 0xC0000005: Access violation reading location 0x00000004.".

My memory_manager code has used the STL code to manage my manager structures.

I debug my code and step into the STL code, I found it used the CRT malloc to assign memory, after deconstruct the static variable "memory_manager mm", system throw the unhandled exception.

Questions:

I don't know how to improve my code to use the placement new / replace the new to my code?

I don't know what has happened in deconstruct the static variable?

I don't know is any better way to resolve my problems metion in the begining of this post?

I have a thinking about create a shared_ptr to deal with it, may be like this:

shared_ptr sp_(new MyClass); 
// inner of shared_ptr: 

// 1. new MyClass use the system allocator to assign memory. 

// 2. In the constructor of the shared_ptr: 

// 2.1 copy the memroy of the (new MyClass) object into our memory: 

//       static memory_manager mm; 

//       void * p = mm.allocate(sizeof obj); 

//       memmove( from obj to p); 

//       delete obj; 

//       return p; 

// 3. Is it right? 

// 4. if it's a array, like new MyClass[10]; we must delete the object 

like this delete [] obj ? How to difference it?

Thanks!

+2  A: 

The problem is that you're overloading the global operator delete and and operator delete[] in memory_manager_main.cpp. As a general guideline, if you overload one of the new or delete operators, you should most likely have to implement overloads for all.

Then internally in your memory manager class you're using std::map and std::multimap, both of which relies on the std::allocator class unless you specify otherwise. This, at least for the version Microsoft provides with Visual Studio, relies on operator delete/operator new for deallocations and allocations.

I'm not sure, but you might either be ending up deleting things with the wrong delete, or you're trying to delete stuff with operator delete in std::map's destructor using operator delete, that relies on the instance of the class you're deleting?

You could possibly implement your own allocator using malloc/free to get around this problem.

Jacob
A: 
  1. reference count the new / delete counter when allocate memory to anaylize the memory leak problem.

I'm pretty sure that MSVC already comes with debug memory allocator which allows to detect such issues. IIRC it can be optionally activated for debug builds.

In fact, when searching for "visual studio memory debugger" first link leads immediately to this page: Memory Leak Detection Enabling.

  1. reduce the memory fragment.

Standard memory allocators are quite resistant to memory fragmentation. You might need alternative memory allocator only if you write application which is expected to run months/years without interruption. But even for the cases replacement of memory allocator is superficial and less reliable compared to the simple resource allocation in advance: allocate all resources which might be needed right after the start of the application.

I don't know how to improve my code to use the placement new / replace the new to my code?

You do not need to do anything special. Placement new doesn't trigger memory allocation - it is just a fancy way to call a constructor on a piece of raw memory. If the raw memory was allocated before with the new then you are all set already.

I don't know what has happened in deconstruct the static variable?

No memory management is involved. Static variables live in data segment, not in heap.

I don't know is any better way to resolve my problems metion in the begining of this post?

My wild guess would be (and this is a usual beginner's error) is that your implementation of memory manager uses dynamic memory and is recursively calling itself.

Dummy00001