问题
My program's architecture involves plugins (dlls) and the exe (obviously). We are the only plugin provider. I was told that allocating memory in a plugin and then freeing it in the exe code was a potential problem if we statically linked the c runtime. However, if we dynamically linked it, there was just one heap and the c runtime had access to all of it. We switched to dynamic linking on the basis of this advice, but all we've seen from the switch is headaches and trouble related to distribution and installation of the new runtimes. (Don't know what we avoided in terms of memory allocation problems.)
What are the memory allocation implications? Say a plugin allocates memory and the exe frees it. Is there different behavior between the static vs dynamically linked c runtime? Will we have trouble statically linking the c runtime if we use plugins? If we switch back to static linking, will that mess up the memory leak detection and crash dump reporting?
Is in line with some questions raised by comments on Which VC++ runtime version do I choose - static or dynamic? specifically Which VC++ runtime version do I choose - static or dynamic?
There is also some discussion at http://msdn.microsoft.com/en-us/library/abx4dbyh(v=VS.100).aspx.
回答1:
If you want to allocate from the heap in one module, and free in another then you simply have to dynamically link the runtime. What's more, all parties must dynamically link the same runtime. Once you do that then there will be no problems.
Now, this is quite a severe constraint to impose on your plugins and you should think twice before doing it. Forcing all plugin authors to upgrade in lock-step with you is a heavy imposition. I would recommend that you consider refactoring your interface so that allocations are always paired with deallocations within a single module. This lifts the constraints I describe above and makes life easier for your plugin authors.
As for why you are still suffering from runtime errors, that's hard to tell. My guess is that not all modules are linking against the same version of the runtime.
In the comments you state that you control all plugins. That means the constraints I discuss above are not an imposition since it is easy for you to use the same compiler version for all modules. However, the rules for dynamic linking with cross-module heap access remain. You must use dynamic linking against the same single version of the runtime.
回答2:
Obviously, the problem is that the plug-in and main app use different and incompatible heap managers that clobber each other's data structures. Using a dynamic CRT theoretically forces both to use the same CRT and therefore both automatically are compatible.
In the general case, it might be best to have the plug-in be responsible for both allocating and deleting all memory it uses. This implies possibly adding APIs to the plug-in to delete objects it previously created and passed back to the main application. This also provides good isolation between the plug-in and the app, allowing the plug-in to use specialized allocators for performance or other reasons. This is what COM does, for instance.
回答3:
Functions to allocate/free memory are paired; you can't call my_malloc() and then use free(), or call C++'s "new" operator and later call FreeMem() from some random library :)
Your plugin needs a well-known way of allocating and freeing memory. If it does malloc(), then your main program can probably just do free(). But if it does something more exotic (Windows has tons of memory allocators available), your plugin API needs to provide a way for the main exe to call into the plugin to free its data.
So if your main program calls
foo = plugin->allocate_something()
then it would be wise for your plugin API to have a corresponding
plugin->free_something (foo)
that the main program can use unambiguously.
来源:https://stackoverflow.com/questions/8157891/memory-allocation-in-static-vs-dynamic-linking-of-c-runtime