0

I am new to boost library and trying boost::scoped_ptr, it states this smart pointer cannot be copied or moved. But I was playing with some code and found an issue. I was able to create new instance of scoped_ptr and initialize it with existing valid scoped_ptr. So if one of the scoped_ptr's scope is over and deallocates the memory , other scoped_ptr still thinks its valid pointer and tries to access. It gave me error at runtime.

I am working on boost library version 1.66, with cygwin g++ compiler and using std=c++03 option while compiling.

#include<boost/scoped_ptr.hpp>
#include<iostream>

using namespace std;

int main(){
    boost::scoped_ptr<int> pi(new int(9));
    cout << *pi << endl;
    cout << uintptr_t(pi.get()) << endl;

    boost::scoped_ptr<int> ppi(pi.get()); // initialized with same memory pointed by pi.
    cout << *ppi << endl;                 // so ownership of same memory is with pi.
    cout << uintptr_t(ppi.get()) << endl; // as well as with ppi.

    pi.reset(new int(12)); //its previous memory location pointing to 9 is deallocated.

    cout << *ppi << endl;                  // throws garbage value.. 
    cout << uintptr_t(ppi.get()) << endl;  // shows same memory location it had previous memory shown by pi. 

    cout << *pi << endl;
    cout << uintptr_t(pi.get()) << endl;

    return 0;
}

So below is the snapshot of code run after compiling fine...

-> g++ -std=c++03 -Wall scoped_ptr.cpp 

-> ./a.exe 
9
25769804960
9
25769804960
-2144292696
25769804960
12
25769879920
Aborted (core dumped)

At end of execution is shows core dump, it incorrectly displayed -2144292696 in above run.

Also I checked boost::scoped_ptr was able to assign it to pointer
int * p = pi.get() statement compiles fine (should this work?)

Is above operation initializing scoped_ptr with other scoped_ptr valid?

Evg
  • 25,259
  • 5
  • 41
  • 83
Rakesh
  • 21
  • 5
  • Are you restricted to c++03? That's an ancient standard and c++11 features std::shared_ptr, std::unique_ptr and std::weak_ptr which may be very well suited to your problem. – RL-S Nov 05 '19 at 15:39
  • wanted to make sure I am using old compiler and boost library. Also as I said I am new to boost, so just playing with it and learning. – Rakesh Nov 05 '19 at 15:59

1 Answers1

1

Is above operation initializing scoped_ptr with other scoped_ptr valid?

No. Boost documentation reads:

explicit scoped_ptr(T * p = 0); // never throws

Constructs a scoped_ptr, storing a copy of p, which must have been allocated via a C++ new expression or be 0.

When you initialize one smart pointer with a raw pointer that is held by another smart one, you do not transfer ownership, you just make a copy of raw a pointer. Hence, that pointer will be deleted several times, which is undefined behavior.

What your code does is essentially this:

int* p = new int;
delete p;  // when you call pi.reset()
delete p;  // when ppi goes out of scope

.get() returns the stored raw pointer. It doesn't check its validity.

To transfer ownership, you should move-assign smart pointer itself. Simple example with std::unique_ptr and C++11:

auto p = std::unique_ptr<int>(new int);
// auto p1 = std::unique_ptr<int>(p.get()); // same error
auto p2 = std::move(p); // fine, transfers ownership from p to p2; 
                        // p will not delete the raw pointer it previously held

boost::scoped_ptr does not support ownership transfer.

Evg
  • 25,259
  • 5
  • 41
  • 83