Search code examples
c++arraysboostruntime-errorshared-ptr

boost smart_ptr runtime error


I'm STILL trying to implement boost shared_ptr in a project I'm creating for homework, and keep running into different errors. Currently, I feel like my code is pretty close to correct, and it builds fine, but I run into a nasty runtime error. I'm just trying to access my Shape class and Point class ToString functions in the MyPrint function below.

My code is as follows:

#include "Point_H.hpp"
#include "Shape_H.hpp"
#include "Array_H.hpp"
#include "ArrayException_H.hpp"
#include "boost/shared_ptr.hpp"

using namespace CLARK::Containers;
using namespace CLARK::CAD;

class S1
{
private:
    boost::shared_ptr<Shape> sp;

public:
    S1(boost::shared_ptr<Shape> value) : sp(value) { cout << "S1 constructor call (default)" << endl; }
    virtual ~S1() { cout << "S1 destructor call" << endl; }
    virtual void print() const { cout << "Shape: " << (*sp).ToString() << endl; }
};

class P1
{
private:
    boost::shared_ptr<Point> pp;

public:
    P1(boost::shared_ptr<Point> value) : pp(value) { cout << "P1 constructor call (default)" << endl; }
    virtual ~P1() { cout << "P1 destructor call" << endl; }
    void print() const { cout << "Point: " << (*pp).ToString() << endl; }
};

void MyPrint()
{
    {
        boost::shared_ptr<Shape> myShape;
        {
            S1 Shape1(myShape);
            Shape1.print();
        }

        boost::shared_ptr<Point> myPoint;
        {
            P1 Point1(myPoint);
            Point1.print();
        }           
    }
}

int main()
{       
    // Typedef for a shared pointer to shape
    // a typedef for an array with shapes stored as shared pointers.
    typedef boost::shared_ptr<Shape> ShapePtr;
    typedef Array<ShapePtr> ShapeArray;

    ShapeArray my_ShapeArray(3);

    my_ShapeArray[0] = ShapePtr (new Point(1,2));

    MyPrint();

    try
    {   
    cout << my_ShapeArray[0]->ToString() << endl;

    return 0;       
    }

    catch(ArrayException& err)
    {
        cout << err.GetMessage() << endl;
    }    
}

The command window displays the following, with a runtime error aborting the program:

Array constructor call

S1 constructor call (default)

Assertion failed: px != 0, file c:\program files x86)\boost\boost_1_51_0\boost\smart_ptr\shared_ptr.hpp, line 418

Could someone please help me? I've been trying to debug this for many hours!

* EDIT:

Per request, Array Default Constructor:

Array Default Constructor:

template <typename Type> class Array
{
private:
Type* m_data; // dynamic array of Type objects
int m_size; // size of array
...
};

template <typename Type>
int Array<Type>::m_default_size = 10;

template <typename Type>
Array<Type>::Array()
{// Default constructor
    m_size = m_default_size;
    m_data = new Type[m_default_size];
    cout << "Array constructor call (default)" << endl;
}

Thanks.


Solution

  • The statement:

    boost::shared_ptr<Shape> myShape;
    

    Default constructs a shared pointer to a Shape, but doing this means that it does not refer to an actual instance (internally it is null). Instead you need to pass your shapes array as an parameter to MyPrint, something like this:

    void MyPrint(const Array<ShapePtr>& shapes)
    {
        for (int i = 0; i < shapes.getSize(); ++i)
        {
            // this guard is necessary if you do not fully populate the array
            if (shapes[i])
            {
                shapes[i]->print();
            }
        }
    }
    

    And call it like this in main:

    MyPrint(my_ShapeArray);
    

    Note that you will need to move your ShapePtr typedef outside of main for this change to work for you.