0

I use smart pointer from Boost library. Suppose I have this object:

boost::shared_ptr<A> a(new A);

a->fileName = "/temp";

In the class B, I have:

bool open(A *a);

and

private: boost::shared_ptr<A> myA;

Then I declare an object B:

boost::shared_ptr<B> b(new B());

b->open(a.get());

bool B::open(A *a)
{
  *B::myA = *a;
}

Those demonstration above is about pass by value parameter. Compiling is fine but when I run it, it gave this error:

/usr/local/include/boost/smart_ptr/shared_ptr.hpp:412: typename boost::detail::shared_ptr_traits<T>::reference boost::shared_ptr<T>::operator*() const [with T = NameSpaceABC::Common::A]: Assertion `px != 0' failed.
Aborted

And for the same question above, what should I change to have: pass by reference parameters? As I am a C# and Java programmer, I just have switched to C++ for a quick project. I am not familiar with using pointers and Boost Smart pointer.

Thanks in advance and I am very appreciated about your help!

olidev
  • 20,058
  • 51
  • 133
  • 197
  • 1
    Have you tried debugging `VImageInputStream::open` to see if either `myA` of `a` is 0 ? The boost assertion is pretty clear : you are dereferencing an empty `shared_ptr`. – icecrime Nov 23 '10 at 09:59
  • Hi, I have checked the answer from Space_C0wb0y below. It is working fine but I am not sure whether it is value passing parameter or reference passing parameter? and how to write 'delete' in destructor for the smart pointer. Thanks in advance – olidev Nov 23 '10 at 10:08
  • The "smart" part of smart pointers is that you don't have to write `delete` anymore. They'll do that for you. When the last `shared_ptr` goes away, it deletes the A object. – MSalters Nov 23 '10 at 10:47
  • Review your questions to accept answers ppl gave you. – karlphillip Nov 25 '10 at 15:01

2 Answers2

2

If you use a smart-pointer pointer for an object once, you should use it for that object always. In your case, open should look like this:

bool B::open(boost::shared_ptr<A> a) {
    myA = a;
}

This way you would have reference semantics for the object passed to open. Your code example tried to assign the object, not the reference. In that case you have to make sure that myA already contains a valid object of type A (preferably in the constructor):

B::B() : myA(boost::make_shared<A>()) {}

And then you can write your open method like this:

bool B::open(const A & a) {
    *myA = a;
}

Also, read this to understand how shared_ptrs work.

Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • Oh Ok. I see, but this is value passing parameter, right? if yes, and how about reference passing parameter? Thanks in advance! – olidev Nov 23 '10 at 10:03
  • @Joesy: The `shared_ptr` *is* the reference. And you pass the reference by value. `shared_ptr` should always be passed by value, because only that way their reference counting works. – Björn Pollex Nov 23 '10 at 10:08
  • I don't think the `shared_ptr` has to be passed by value in the first case. The end result is that you'd have two pointers to the same object. There is no need to have temporarily a third pointer as well. – visitor Nov 23 '10 at 11:04
0

You are dereferencing a shared_ptr that is not pointing to an object.

It seems to me that there might be two possible scenarios.

1) You want to share the A object in main and B. Then you should pass a shared_ptr to open.

bool B::open(const shared_ptr<A>& a)
{
    myA = a;
}

//called with
b->open(a);

2) You want B to make a copy of the value. Then it might make sense to pass the object.

bool B::open(const A& a)
{
    myA.reset(new A(a));
}

//called with
b->open(*a);

Or perhaps, if myA is already pointing to an object, you won't need to allocate a new one.

bool B::open(const A& a)
{
    if (myA)
        *myA = a;
    else
        myA.reset(new A(a));
}
visitor
  • 8,564
  • 2
  • 26
  • 15