title: Virtual functions in dynamically linked C++ libs impossible?
body: <p>As an example, this code segfaults (see comment in main.cpp).</p>
  
  <p><strong>hello.h</strong></p>
  
  <pre><code>struct A { virtual ~A() {} };
  </code></pre>
  
  <p><strong>hello.cpp</strong></p>
  
  <pre><code>#include "hello.h"
  
  extern "C" {
      void hello(A*&amp; a) {
          a = new A;
      }
  }
  </code></pre>
  
  <p><strong>main.cpp:</strong></p>
  
  <pre><code>#include &lt;cassert&gt;
  #include &lt;dlfcn.h&gt;
  
  #include "hello.h"
  
  int main() {
  
      void* handle = dlopen("./hello.so", RTLD_LAZY);
      assert(handle);
  
      typedef void (*hello_t)(A*&amp; a);
      hello_t hello = (hello_t) dlsym(handle, "hello");
      assert(hello);
  
      A* a = nullptr;
      hello(a);
      dlclose(handle);
  
      delete a; // -&gt; segfault
  }
  </code></pre>
  
  <p><strong>compile</strong></p>
  
  <pre><code>g++ -Wall -std=c++11 -g main.cpp -ldl -o main
  g++ -Wall -std=c++11 -g -shared -fpic hello.cpp -o hello.so
  </code></pre>
  
  <p>The reason: <code>A</code> contains a virtual table. When <code>a</code> is being allocated, the virtual table contains pointers to the function segment of <code>hello.so</code>. After a call to <code>dlclose()</code>, this function segment may get invalid, causing the pointers to get invalid, and thus, the <code>delete a</code> calls functions which are out of memory.</p>
  
  <p>So far so clear. My questions are, all assuming that you <code>dlclose()</code> your library and then continue using the objects:</p>
  
  <ol>
  <li>Is it impossible to allocate objects of classes with virtual destructors in an .so file? Is there no better trick than implementing your own vtable on the heap?</li>
  <li>If it is impossible, isn't it dangerous to allocate anything you don't know about in a shared library? Even if you know that <code>std::string</code> is guaranteed to be implemented without a virtual destructor, who knows if it holds an internal object with one?</li>
  </ol>