Boost logo

Boost Users :

Subject: Re: [Boost-users] Use boost::shared_ptr with boost::adaptors
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-04-28 16:45:06


On Sat, Apr 28, 2012 at 7:10 AM, tolik levchik <endight_at_[hidden]> wrote:

> The following code gives me segfault. But if `foo_ptr` is `foo*` it works
> fine.
>
> #include <vector>
> #include <boost/range/adaptor/indirected.hpp>
> #include <boost/range/adaptor/transformed.hpp>
> #include <boost/range/algorithm/for_each.hpp>
> #include <boost/bind.hpp>
> #include <boost/shared_ptr.hpp>
>
> struct foo{
> foo(int _i):
> i(_i){}
> virtual void bar() const{
> std::cout << "foo::bar::i " << i << std::endl;
> }
> int i;
> };
>
> typedef boost::shared_ptr<foo> foo_ptr;
> //typedef foo* foo_ptr;
> foo_ptr trasform(int i){
> return foo_ptr(new foo(i));
> }
> int main(){
> std::vector<int> vec;
> vec.push_back(1);
>
> using namespace boost::adaptors; using boost::bind;
> boost::for_each(vec
> | transformed(bind(&trasform, _1))
> | indirected,
> bind(&foo::bar, _1));
> }
> Is it expected behavior of adaptors ?
>

I think so. Here's my guess what's going on. Consider what the dereference
function might look like for an iterator to the range

vec | transformed(bind(&transform, _1)) | indirected

foo& dereference()
{
    int& i = *vec_it; // dereference iterator to vec
    foo_ptr = transform(i); // pass i through bind(&transform, _1)
    foo& x = *foo_ptr; // pass foo_ptr through indirected
    return x;
}

Sadly, the only foo_ptr "backing" the foo& goes out of scope once the foo&
is returned, so that foo object is deleted and you get a dangling reference.

I don't think there's an obvious alternate implementation that will allow
you to get away with the above. When you start chaining together range
adaptors, especially transforms, you have to consider whether the argument
to the transformation function needs to persist for the result to be remain
valid.

HTH,

- Jeff



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