Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy isn't my new operator called
    text
    copied!<p>I wanted to see that a dynamically loaded library (loaded with dlopen etc.) really uses its own new an delete operators and not these ones defined in the calling program. So I wrote the following library.cpp</p> <pre><code>#include &lt;exception&gt; #include &lt;new&gt; #include &lt;cstdlib&gt; #include &lt;cstdio&gt; #include "base.hpp" void* operator new(size_t size) { std::printf("New of library called\n"); void *p=std::malloc(size); if (p == 0) // did malloc succeed? throw std::bad_alloc(); // ANSI/ISO compliant behavior return p; } void operator delete(void* p) { std::printf("Delete of library called\n"); std::free(p); } class Derived : public Base { public: Derived() : Base(10) { } }; extern "C" { Base* create() { return new Derived; } void destroy(Base* p) { delete p; } } </code></pre> <p>and compiled it with</p> <pre><code>g++ -g -Wall -fPIC -shared library.cpp -o library.so </code></pre> <p>or as Employed Russian suggested to try (but in the end nothing changed)</p> <pre><code>g++ -g -Wall -fPIC -shared -Wl,-Bsymbolic library.cpp -o library.so </code></pre> <p>The class Base is only holding an int value and a function get_value() to get this value. After that I wrote client.cpp like this</p> <pre><code>#include &lt;exception&gt; #include &lt;new&gt; #include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;cstdio&gt; #include &lt;dlfcn.h&gt; #include "base.hpp" void* operator new(size_t size) { std::printf("New of client called\n"); void *p=std::malloc(size); if (p == 0) // did malloc succeed? throw std::bad_alloc(); // ANSI/ISO compliant behavior return p; } void operator delete(void* p) { std::printf("Delete of client called\n"); std::free(p); } typedef Base* create_module_t(); typedef void destroy_module_t(Base *); int main() { void* handle = dlopen("./library.so", RTLD_LAZY); if (handle == NULL) { std::cout &lt;&lt; dlerror() &lt;&lt; std::endl; return 1; } create_module_t* create_module = NULL; void* func = dlsym(handle, "create"); if (func == NULL) { std::cout &lt;&lt; dlerror() &lt;&lt; std::endl; return 1; } else create_module = (create_module_t *)func; destroy_module_t* destroy_module = NULL; func = dlsym(handle, "destroy"); if (func == NULL) { std::cout &lt;&lt; dlerror() &lt;&lt; std::endl; return 1; } else destroy_module = (destroy_module_t *)func; Base* a = create_module(); std::cout &lt;&lt; "Value: " &lt;&lt; a-&gt;get_value() &lt;&lt; std::endl; destroy_module(a); return 0; } </code></pre> <p>and compiled it with</p> <pre><code>g++ -Wall -g -o client -ldl client.cpp </code></pre> <p>Executing client I only get a "New of client called" and a "Delete of client called". Even if I use the compiler switch -Bsymbolic for the library like Employed Russian suggested.</p> <p>Now: What went wrong? I thought shared library are using their own new/delete and therefore you have to provide next to the factory create a destructor destroy in the library code.</p> <p>Supplementary question: Why do I need the destroy(Base* p) function? If this function only calls the delete-operator of the client I could also do it by myself, i.e "delete a" instead of destroy_module(a) in the next to last line.</p> <p>Answer I found: The library can also provide a new/delete-operator pair. So if I use first the library's new and later the client's delete I can probably step into a pitfall. Sadly until now I never saw my library using it's own new or delete... So the original question still isn't answered.</p> <p>Supplement: I'm only referring to the Linux platform.</p> <p>Edit: The important parts are in the comments to Employed Russian's Answer. So I'm giving the main clue in a nutshell: If one calls the gcc this way</p> <pre><code>g++ -Wall -g -fPIC -shared library.cpp -o library.so -Wl,-Bsymbolic </code></pre> <p>the library will use it's own new/delete operators. Otherwise results</p> <pre><code>g++ -Wall -g -fPIC -shared library.cpp -o library.so </code></pre> <p>in a library that's using the new/delete operators of the calling program. Thanks to Employed Russian!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload