• Advertisement
Sign in to follow this  

Using Paul Nettle's Mem Manager Inside a DLL

This topic is 3952 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, I am using Paul Nettle's Memory Manager inside a DLL. I found out that it works fine to find memory leaks inside the DLL, but it doesn't detect leaks in an executable linked to this DLL (even with the Memory Manager header enabled). Has anyone faced the same problem and found a clean solution for it?

Share this post


Link to post
Share on other sites
Advertisement
If the client of the DLL uses malloc/free or new/delete, it will use the native memory manager of the client application, not the DLL. The way to change this would be to call your own new/delete allocators which, under the cover, use the DLL's allocators & memory manager. I can't think of a way a DLL can hook the allocator of the client code unless the client was compiled to take advantage of a different allocation system than just raw new/delete.

Does that make sense?

You could use something like this:



// Define abstract interface to an allocator

class IAllocator
{
public:

virtual void* Allocate( size_t size ) = 0;
virtual void Deallocate( void* address ) = 0;

};

extern IAllocator* GetAllocator();

// Define macros to use it

#define MYNEW(x) reintepret_cast<x*>(GetAllocator()->Allocate(sizeof(x)))
#define MYDELETE(x) GetAllocator()->Deallocate(x)

// Use MYNEW and MYDELETE everywhere, and/or overload new and delete
// ie:

Teapot* pTeapot = MYNEW(Teapot);

// Create a default implementation of the alocator

class DefaultAllocator : public IAllocator
{
public:

virtual void* Allocate( size_t size ) { return malloc( size ); }
virtual void Deallocate( void* address ) { free( address ); }

};

// In your DLL create your own allocator
class PaulNettleAllocator : public IAllocator
{
public:

virtual void* Allocate( size_t size ) { return PaulNettleMalloc( size ); }
virtual void Deallocate( void* address ) { PaulNettleFree( address ); }

};

// In your application that hosts the DLL declare the default & global allocator

static DefaultAllocator theDefaultAllocator;

IAllocator* s_pCurrentAllocator = &theDefaultAllocator;

IAllocator* GetAllocator() { return s_pCurrentAllocator; }

// Add some extra functions for setting a new allocator

IAllocator* SetNewAllocator( IAllocator* pAllocator )
{
IAllocator* pOldAllocator = pCurrentAllocator ;
pCurrentAllocator = pAllocator;
return pOldAllocator;
};




Now, when you DLL starts up, have it call SetNewAllocator() with it's PaulNettle allocator and save the old allocator returned. When it unloads have it restore the old allocator. You could instead use a stack so the DLL just pops its allocator and the host application can keep track of the allocators.


This is similiar to how we've done some of our console work.

Hope that helps/makes sense??


Share this post


Link to post
Share on other sites
Hey Sphet!

Yes, that does make sense. Look, it will take a while for me to give it a try. I will let you know when I do. Thanks for the help!

Cheers!

Share this post


Link to post
Share on other sites
Hey Sphet!

Thanks for the hint man. Actually, I got that working! I didn't implement a stack, but a list of modules that are hooked to the memory manager. I didn't test all of it yet, but I am afraid that DLLs that use the memory manager that is inside the main DLL may be loaded/unloaded not in FIFO order, especially those that are loaded dynamically. All of this gave me a better understanding of memory management.

One small detail of how I implemented it: I created a .inl file that has the bodies of the allocators and a static instance of a class that puts/removes the current module in the list of modules currently hooked to the memory manager opon its construction/destruction. This .inl file is to be included once in every module where memory manager is to be used. I liked this solution and so far I see no downside in it. Having you used a similar system in consoles, I would like to know if you see any problem in using this approach?

Thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement