title: Destroying a shared std::vector in another process
body: <p>I'm trying to transfer a <code>std::vector&lt;std::string&gt;</code> to a newly forked process via Boost.Interprocess, so that the child process takes ownership of it and destroy it. Retrieving and reading the vector works, however I'm getting an access violation upon destroying it. I gather that the allocator embarks some state with pointers which point into the parent's address space and are meaningless in the child's one.</p>
  <p>How am I supposed to create that vector in the parent and destroy in the child correctly ?</p>
  <h3>Parent process code:</h3>
  <pre class="lang-cpp prettyprint-override"><code>namespace ip = boost::interprocess;
  
  template &lt;class T&gt;
  using ip_allocator = ip::allocator&lt;T, ip::managed_shared_memory::segment_manager&gt;;
  
  template &lt;class T&gt;
  using ip_vector = std::vector&lt;T, ip_allocator&lt;T&gt;&gt;;
  
  int CALLBACK WinMain(
      _In_ HINSTANCE,
      _In_ HINSTANCE,
      _In_ LPSTR,
      _In_ int
  ) {
      ip::shared_memory_object::remove(&quot;MyTestShm&quot;);
      ip::managed_shared_memory mshm{ ip::open_or_create, &quot;MyTestShm&quot;, 1024 * 1024 };
  
      ip_allocator&lt;int&gt; intAlloc{ mshm.get_segment_manager() };
  
      mshm.construct&lt;ip_vector&lt;int&gt;&gt;(&quot;ForkData&quot;)(
          ip_vector&lt;int&gt;{ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, intAlloc}
      );
  
      boost::process::spawn(L&quot;Executor.exe&quot;, L&quot;ForkData&quot;);
  }
  </code></pre>
  <h3>Child process (<code>Executor.exe</code>) code:</h3>
  <pre class="lang-cpp prettyprint-override"><code>int wmain(int argc, wchar_t **argv) try {
      namespace ip = boost::interprocess;
  
      // Kludge to attach the debugger and force continuation
      bool volatile coin = true;
      while (coin)
          ::Sleep(1000);
  
      ip::managed_shared_memory mshm{ ip::open_only, &quot;MyTestShm&quot; };
      auto const * const fd = mshm.find&lt;ip_vector&lt;int&gt;&gt;(&quot;ForkData&quot;).first;
  
      if(!fd)
          return 1;
  
      for (int i : *fd)
          std::cout &lt;&lt; i &lt;&lt; ' ';
      std::cout &lt;&lt; '\n';
  
      mshm.destroy_ptr(fd); // Crashing line
  }
  catch (std::exception const &amp;exc) {
      std::cerr
          &lt;&lt; &quot;Unhandled &quot; &lt;&lt; boost::typeindex::type_id_runtime(exc).pretty_name() &lt;&lt; &quot;:\n&quot;
          &lt;&lt; exc.what() &lt;&lt; '\n';
      return 1;
  }
  </code></pre>
  <h3>Error and callstack:</h3>
  <blockquote>
  <p>Exception thrown: read access violation.
  <code>_Pnext</code> was <code>0x21FE21200B0</code>. occurred</p>
  </blockquote>
  <pre class="lang-none prettyprint-override"><code>Executor.exe!std::_Container_base12::_Orphan_all() Line 221
  Executor.exe!std::_Vector_alloc&lt;std::_Vec_base_types&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt; &gt;::_Orphan_all() Line 536
  Executor.exe!std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;::_Tidy() Line 1913
  Executor.exe!std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;::~vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;() Line 894
  Executor.exe!std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt;::`scalar deleting destructor'(unsigned int)   Executor.exe!boost::interprocess::ipcdetail::placement_destroy&lt;std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt; &gt;::destroy_n(void * mem, unsigned __int64 num, unsigned __int64 &amp; destroyed) Line 61
  Executor.exe!boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt;::priv_generic_named_destroy&lt;char&gt;(const char * name, boost::interprocess::iset_index&lt;boost::interprocess::ipcdetail::index_config&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt; &gt; &gt; &amp; index, boost::interprocess::ipcdetail::in_place_interface &amp; table, boost::interprocess::ipcdetail::bool_&lt;1&gt; is_intrusive_index) Line 976
  Executor.exe!boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt;::priv_generic_named_destroy&lt;char&gt;(boost::interprocess::ipcdetail::block_header&lt;unsigned __int64&gt; * block_header, boost::interprocess::iset_index&lt;boost::interprocess::ipcdetail::index_config&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt; &gt; &gt; &amp; index, boost::interprocess::ipcdetail::in_place_interface &amp; table, boost::interprocess::ipcdetail::bool_&lt;0&gt; is_node_index) Line 929
  Executor.exe!boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt;::priv_destroy_ptr(const void * ptr, boost::interprocess::ipcdetail::in_place_interface &amp; dtor) Line 777
  Executor.exe!boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt;::destroy_ptr&lt;std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt; &gt;(const std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt; * p) Line 550
  Executor.exe!boost::interprocess::ipcdetail::basic_managed_memory_impl&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index,8&gt;::destroy_ptr&lt;std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt; &gt;(const std::vector&lt;int,boost::interprocess::allocator&lt;int,boost::interprocess::segment_manager&lt;char,boost::interprocess::rbtree_best_fit&lt;boost::interprocess::mutex_family,boost::interprocess::offset_ptr&lt;void,__int64,unsigned __int64,0&gt;,0&gt;,boost::interprocess::iset_index&gt; &gt; &gt; * ptr) Line 608
  Executor.exe!wmain(int argc, wchar_t * * argv) Line 31
  Executor.exe!invoke_main() Line 91
  Executor.exe!__scrt_common_main_seh() Line 288
  Executor.exe!__scrt_common_main() Line 331
  Executor.exe!wmainCRTStartup() Line 17
  kernel32.dll!BaseThreadInitThunk()
  ntdll.dll!RtlUserThreadStart()
  </code></pre>