Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory allocation and deallocation across dll boundaries

I understand that memory allocations made in one dll then subsequently free'd in another can cause all sort of problems, especially regarding the CRT. These sorts of problems are especially problematic when it comes to exporting STL containers. We've experienced these sorts of problems before (when writing custom Adobe plugins that linked with our libraries) and we've worked round these issues by defining our own allocator that we use in all our containers, eg:

typedef std::vector < SessionFields, 
        OurAllocator < SessionFields > > 
        VectorSessionFields;

typedef std::set < SessionFields, 
        std::less < SessionFields >, 
        OurAllocator < SessionFields > > 
        SetSessionFields;

This has worked well when passing types to/from our code, however we've hit a problem in that we're now having to call a function in Adobe's SDK that returns a populated vector which causes a crash when it goes out of scope.

Obviously, it's a problem with memory being allocated in Adobe's SDK belonging to a different heap when it's finally free'd in my code. So I'm thinking that maybe I could do something clever like somehow overriding or exporting the allocator used in their SDK so I could use it to clean up containers returned from their functions.

I'm also looking at writing a wrapper or some sort of thunking layer whereby STL containers would be safely marshalled between my code and the SDK (although this does sound very messy).

Alternatively, I'm also looking at using GetProcessHeaps to identify the heap used from within the SDK, and try to free against this heap, instead of the default heap.

Has anyone any advice on how we can solve this problem?

like image 774
Alan Avatar asked Aug 27 '09 22:08

Alan


1 Answers

Ironically enough, the Adobe Source Libraries has a adobe::capture_allocator class that was written specifically with this kind of DLL safety in mind. The way it works is to capture the local new and delete at this point it is instantiated, and to carry them both around for the lifetime of the object. (See adobe::new_delete_t for details on how it does this, especially the implementation here.) Deallocations take place with the captured delete routine, guaranteeing that no matter where you are you are deleting with the proper delete.

You can see capture_allocator used throughout the version_1 types in the Adobe Source Libraries, such as adobe::any_regular_t and adobe::copy_on_write. capture_allocator should be compatible with all STL container types as well.

Update: capture_allocator is not standard-compliant because it retains state. This should not be a big hindrance to its usability, but it does mean its use is not guaranteed to work with standard-compliant containers.

like image 144
fbrereto Avatar answered Oct 27 '22 10:10

fbrereto