Boost logo

Boost Users :

Subject: Re: [Boost-users] [Interprocess] shared_ptr in shared memory and inheritance
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2009-02-09 12:51:17


You're probably doing something wrong, shared_ptr doesn't require
virtual destructor to call the correct destructor. Here is a working
example: http://codepad.org/sktELTDk

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

On Mon, Feb 9, 2009 at 9:26 AM, Gaetan Gaumer <gaetan.gaumer_at_[hidden]> wrote:
> Hello,
> we would like to store collections of differents objects derived from a same
> base class in a shared
> memory segment, and use polymorphism to manipulate them using
> shared_ptr<base>.
> But as we can't have virtual functions in shared memory we are exploring
> this solution :
> We designed 2 parallels hierarchies of classes
> - A hierarchy of empty objects in process memory with virtual functions
> (polymorphism) (ex : class A)
> - A hierarchy of data objects in shared memory without virtual functions
> (class A_data)
>
> A "process memory" object stores a weak_ptr to the "shared memory" data
> object.
> Use of data are encapsuled in accessors which take care of weak_ptr locking
> and concurrent access.
>
> I don't know if this is a good design (any opinions ?) but it seems to work
> well... until the destruction
> of "shared memory" objects.
> The wrong destructor is used (the base one) instead of the destructor of the
> derived class,
> probably because the destructor is not virtual...
> So I'm currently stuck and I'm looking for some advices.
>
> Here is a little code demonstrating the problem :
> #include <boost/interprocess/managed_shared_memory.hpp>
> #include <boost/interprocess/smart_ptr/shared_ptr.hpp>
> #include <iostream>
> using namespace boost::interprocess;
> using namespace std;
> class base {
> protected :
> int id;
> public:
> base(int i=0):id(i){};
> ~base(){cout << "base dtor" << endl;}
> int getId() const {return id;}
> };
> class derived : public base {
> protected:
> double data;
> public:
> derived(int i=0, double d=0): base(i), data(d){};
> ~derived(){cout << "derived dtor" << endl;}
> double getData(){return data;}
> };
> typedef managed_shared_ptr<base, fixed_managed_shared_memory>::type
> base_shared_ptr;
> int main (){
> fixed_managed_shared_memory
> segment(open_or_create,"sharedPtrSharedMemoryTest", 2048);
> // does not compile but that's what I would like
> //base_shared_ptr baseSP =
> make_managed_shared_ptr(segment.construct<derived>(anonymous_instance)(2,3.0),
> segment);
> // turnaround
> base_shared_ptr baseSP =
> make_managed_shared_ptr((base*)segment.construct<derived>(anonymous_instance)(2,3.0),
> segment);
> cout << "baseSP->getId() =" << baseSP->getId();
> cout <<", baseSP->getData() = " <<
> static_pointer_cast<derived>(baseSP)->getData() << endl;
> baseSP.reset(); // don't know why but base dtor is called 3 times !!!
> }
> I can live with static_pointer_cast<> because they'll be hidden in
> accessors.
> But I really need that the right destructor (here ~derived()) will be called
> as it's cause some asserts in real case :
> include/boost/interprocess/detail/segment_manager_helper.hpp:176: static
> boost::interprocess::detail::block_header*
> boost::interprocess::detail::block_header::block_header_from_value(const
> void*, size_t, size_t): Assertion `hdr->m_value_alignment == algn' failed.
> The commented call to make_managed_shared_ptr makes gcc complains with
> (thanks gfilt for formatting) :
> sharedPtrSharedMemoryTest.cc:30: error: conversion from
> `boost::interprocess::shared_ptr<
> derived
> , boost::interprocess::allocator<
> void
> , boost::interprocess::segment_manager<
> char
> , boost::interprocess::rbtree_best_fit<
> boost::interprocess::mutex_family, void *, 0u
> >, boost::interprocess::iset_index
> >
> >, boost::interprocess::deleter<
> derived
> , boost::interprocess::segment_manager<
> char
> , boost::interprocess::rbtree_best_fit<
> boost::interprocess::mutex_family, void *, 0u
> >, boost::interprocess::iset_index
> > > >' to non-scalar type
> `boost::interprocess::shared_ptr<
> base
> , boost::interprocess::allocator<
> void
> , boost::interprocess::segment_manager<
> char
> , boost::interprocess::rbtree_best_fit<
> boost::interprocess::mutex_family, void *, 0u
> >, boost::interprocess::iset_index
> >
> >, boost::interprocess::deleter<
> base
> , boost::interprocess::segment_manager<
> char
> , boost::interprocess::rbtree_best_fit<
> boost::interprocess::mutex_family, void *, 0u
> >, boost::interprocess::iset_index
> >
> >
> >' requested
> Any help will be welcome.
> Gaetan
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net