Browsing though the forum I came across several posts covering memory ownership problems like that one I've depicted on my own concerning STL and MinGW's gcc.
Now I've seen those problems the other way round, meaning with Irrlicht's idea of container classes, meaning that one may run into trouble when the DLL manipulates containers created by the EXE or vice versa.
I think the root of the problem is that much of the code making up the container classes is placed in the header files rather than the .cpp source code files. May be good for optimization and inlining but separates the memory management in the code and the DLL.
There are several approaches to cover that problem.
The simplest would be to build a static library rather than a dynamic one, thus enforcing both the library and the EXE to use the same allocator routines. With Irrlicht it would be allowed to do so, countrary to the libraries which are licensed under the LGPL where static linking falls under the term 'inclusion in your works'.
But is there a way to instruct the routines in a DLL which memory manager to use when it called 'new', 'delete' and/or 'malloc()' and 'free()' ? I think that would be a more elegant way to handle memory ownership problems - having memory management explicitely handled by one and the same authority.
Memory Ownership considerations
-
Baal Cadar
- Posts: 377
- Joined: Fri Oct 28, 2005 10:28 am
- Contact:
Some one please correct me if I'm wrong, but isn't this memory ownership problem simply solved by using the same dynamic runtime lib for all DLLs/Exes used?
Using MS compiler/linker the option /MD (/MDd respectivly for debug) makes the exe link to the dynamic multithreaded C runtime lib. When you build Irrlicht with the same setting (which is the default I believe), then it is ensured that the same memory allocation and deallocation routines are used by all components.
Our project is seperated into various DLLs and Exes, where STL containers and strings are used as parameter type in virtually all the DLL interfaces and setting them all to the same runtime lib solved the memory ownership problem for us.
The problem with static linking is, that you have to be careful, if you use additional DLLs (like for plugins), because then you have two distinct potential allocators/deallocators. One on the plugin-DLL and one on the main app. Leading to exactly the problem tried to be solved.
gcc is only used on Linux in our project, but no problem occured there either. Though I am not responsible for the Linux build and have no clue there.
Using MS compiler/linker the option /MD (/MDd respectivly for debug) makes the exe link to the dynamic multithreaded C runtime lib. When you build Irrlicht with the same setting (which is the default I believe), then it is ensured that the same memory allocation and deallocation routines are used by all components.
Our project is seperated into various DLLs and Exes, where STL containers and strings are used as parameter type in virtually all the DLL interfaces and setting them all to the same runtime lib solved the memory ownership problem for us.
The problem with static linking is, that you have to be careful, if you use additional DLLs (like for plugins), because then you have two distinct potential allocators/deallocators. One on the plugin-DLL and one on the main app. Leading to exactly the problem tried to be solved.
gcc is only used on Linux in our project, but no problem occured there either. Though I am not responsible for the Linux build and have no clue there.
-
hybrid
This topic had been raised several weeks ago already, and I just rushed through some M$ documentation to get an idea of why this could happen at all. And from the results I found at that time I'd say that just using the same C library will not help. Windows uses a process like mechanism when using dlls, so basically each dll has its own process with memory space etc. If you allocate an adress in one app and pass it to the dll for explicit destruction (free or delete) you should get a memory access violation due to the different process spaces. But in fact this is rather uncommon because usually you'll call a destructor which passes back the process activity to the originating app.
Hmm rethinking what I just said I must admit that indeed for all the rest it shoudl be enough to have the same malloc and free throughout all libraries as you said. Because then each time a free is called the very same dll would be used for it.
Anyway, this is real bullshit, because you have to be rather careful which dlls to use and probably change your complete project and dependant libraries if one comes up with a change to a different C library. I'm really sorry for all you people out there who have to cope with these problems. And I really asked myself why Windows programs tend to crash very soon
Hmm rethinking what I just said I must admit that indeed for all the rest it shoudl be enough to have the same malloc and free throughout all libraries as you said. Because then each time a free is called the very same dll would be used for it.
Anyway, this is real bullshit, because you have to be rather careful which dlls to use and probably change your complete project and dependant libraries if one comes up with a change to a different C library. I'm really sorry for all you people out there who have to cope with these problems. And I really asked myself why Windows programs tend to crash very soon
-
Eternl Knight
- Posts: 313
- Joined: Tue Nov 01, 2005 5:01 am
The solution to this problem used by STL is the use of "allocator" objects. These objects are created by the process space in which the STL container is created, and hence has an internal reference to the memory management functions compiled into the DLL/EXE. Whenever it needs to allocate/free memory - it calls the allocator objects which then call the correct memory functions.
The problem with Irrlicht is that EVERYTHING in the container classes is inline templated code. As such, the memory allocation/free routines are compiled into the both processes wherever they are used (i.e. in the middle of a client functiion).
*shrug* My solution was to convert my Irrlicht over to STL. I takes about an hour (to do from scratch) and the difference in performance is negligible.
--EK
The problem with Irrlicht is that EVERYTHING in the container classes is inline templated code. As such, the memory allocation/free routines are compiled into the both processes wherever they are used (i.e. in the middle of a client functiion).
*shrug* My solution was to convert my Irrlicht over to STL. I takes about an hour (to do from scratch) and the difference in performance is negligible.
--EK