Open thehans opened 2 years ago
Thanks @thehans for all your feedback!
I can see it is a bit confusing and will try to improve the documentation; However, it is partly confusing because there is inherent complexity in many ways to override malloc
: use #defines (mimalloc-override.h
), use static linking override (mimalloc-override.o
), use dynamic override (e.g. LD_PRELOAD), use from C or C++, and the various ways the different OS's and linkers work. It would be great if there is was one standard way to do things but there just isn't and the right way depends the application.
Having said that:
MI_OVERRIDE=ON
defines all the standard malloc
api entry points, and also the C++ new
/delete
entry points. The only reason to disable this is either that you never use it (as the application calls the mi_
api's specifically), or when you linker would complain about multiple definitions (as on Windows without weak symbols).
On Unix systems, you can thus use static linking override, or LD_PRELOAD, such that all allocation goes via mimalloc.
However, if you compile mimalloc with MI_OVERRIDE=ON
, and also include mimalloc-new-delete.h
in your application you will now define the overrides for C++ new
/delete
twice (once in libmimalloc
and once in your application) so that it is where your errors come from.
But on Windows, each DLL has its own namespace, and when overriding it uses dynamic patching which can only redirect basic malloc
/free
calls. That means that each C++ (application) module uses its own new
/delete
which eventually will call the (redirected) malloc
/free
. This turns out to be not as efficient as it can be and it is better to then overload the C++ new
/delete
to directly use the mimalloc
ones where possible -- hence, on Windows with dynamic overriding, you should include mimalloc-new-delete.h
if you can.
Of course, if Boost for example also overrides C++ new
/delete
then that is another conflict. Not sure if that is what you saw with clang-14.
And on macOS ...
As you can see, a lot of this is beyond the scope of mimalloc but more about linking C/C++ on various platforms. I will try if I can make this more clear with a nice diagram or something. The current goal is at least to make everything work out-of-the-box on the various platforms without needing special make flags etc.
Does
MI_OVERRIDE=ON
cmake option imply that new/delete are overridden in addition to the C malloc/etc interface?If I compile with
MI_OVERRIDE
on Linux, I get "multiple definition" linker errors when I try to#include <mimalloc-new-delete.h>
Here are the messages from
gcc-10
:(I got even stranger messages if I tried to build with
clang-14
, where it claimed they were redefined inboost/system/detail/std_interoperability.hpp
which I assume was some kind of compiler bug since I saw no such definitions in that file)Is the answer specific to target OS? (i.e.
MI_OVERRIDE
implies new/delete override, everywhere EXCEPT on Windows?) I'm wondering about this sinceMI_OVERRIDE
defaults ON, and I see this preprocessor conditional in the tests: https://github.com/microsoft/mimalloc/blob/38a03229c89afbf2722e48c63da696bf11589dee/test/main-override.cpp#L17-L19