Boost logo

Boost Users :

Subject: [Boost-users] [SmartPtr] enable_shared_from_raw / weak_from_raw remains not associated
From: Slava (Viatcheslav.Sysoltsev_at_[hidden])
Date: 2013-05-16 05:58:27


I'm converting existing code with parent-child object tree to boost
shared_ptr/weak_ptr with parents having [now shared] ownership over the
children and children having weak reference to the parent. In the existing
code a parent usually becomes the children as constructor parameters, and
thus I have to extract the weak_ptr to "this" in constructor, which does
not work with current boost::enable_shared_from_this implementation. So I
am looking to enable_shared_from_raw alternative, which is promising, but
unfortunately does not quite work for my case. Here is a small example
demonstrating the issue:

test.cpp:

#include <boost/smart_ptr/enable_shared_from_raw.hpp>
#include <iostream>

struct Parent;

struct Child
{
     Child()
     {
         std::cout << "Construct Child" << std::endl;
     }
     ~Child()
     {
         std::cout << "Destruct Child" << std::endl;
     }

     boost::weak_ptr<Parent> parent;
};

struct Parent : public boost::enable_shared_from_raw
{
     Parent(boost::shared_ptr<Child> _child)
     {
         std::cout << "Construct Parent" << std::endl;
         this->child = _child;
         this->child->parent = boost::weak_from_raw(this);
     }

     ~Parent()
     {
         std::cout << "Destruct Parent" << std::endl;
     }

     boost::shared_ptr<Child> child;
};

int main()
{
     boost::shared_ptr<Child> child(new Child());
     boost::shared_ptr<Parent> parent(new Parent(child));
     std::cout << "child->parent is " << (child->parent.lock() ? "not null"
: "null") << std::endl;
     parent.reset();
     std::cout << "child must be alone" << std::endl;
     std::cout << "child->parent is " << (child->parent.lock() ? "not null"
: "null") << std::endl;
     return 0;
}

`g++ -g -O0 test.cpp && valgrind a.out` produces:
==8467== Memcheck, a memory error detector
==8467== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==8467== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==8467== Command: a.out
==8467==
Construct Child
Construct Parent
child->parent is null
Destruct Parent
child must be alone
child->parent is null
Destruct Child
==8467==
==8467== HEAP SUMMARY:
==8467== in use at exit: 0 bytes in 0 blocks
==8467== total heap usage: 4 allocs, 4 frees, 112 bytes allocated
==8467==
==8467== All heap blocks were freed -- no leaks are possible
==8467==
==8467== For counts of detected and suppressed errors, rerun with: -v
==8467== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

The problem is that the weak_ptr to parent in child does not get
associated properly, when shared_ptr to parent is finally complete. Do I
expect too much from enable_shared_from_raw or did I hit some bug in the
implementation? I'm using boost 1.53.0-2 on Archlinux.

-- Slava


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