mblw
mblw

Reputation: 1798

C++ std::shared_ptr and vector crash

Why this code crash?

class Point {
public:
    double x;
    double y;
};

class Edge {
public:
    Point org;
    Point dst;

    Edge(const Point& org, const Point& dest) {
        this->org = org;
        this->dst = dest;
    }
};

class Box {

    private:

    std::vector<std::shared_ptr<Edge>> _edges;

    void _init(const Point& lb, const Point& rt) {
        std::cout << "Initialize Box ... " << std::endl;

        // CRASH SOMEWHERE HERE ...

        this->_edges.reserve(4);

        this->_edges[0] = std::make_shared<Edge>(lb.x, lb.y, rt.x, lb.y);
        this->_edges[1] = std::make_shared<Edge>(rt.x, lb.y, rt.x, rt.y);
        this->_edges[2] = std::make_shared<Edge>(rt.x, rt.y, lb.x, rt.y);
        this->_edges[3] = std::make_shared<Edge>(lb.x, rt.y, lb.x, lb.y);

        std::cout << "Box object initialized" << std::endl;
    }

    public:
    Box(const Point& lb, const Point& rt) {
        this->_init(lb, rt);
    }
};

Upvotes: 0

Views: 1025

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254431

reserve reserves space for vector elements, but doesn't add any accessible elements to the vector. The size is still zero, so that your accesses to _edges[0] etc. are out of bounds.

Instead, either use resize to resize the vector, using your existing code to reassign the elements:

this->_edges.resize(4);

this->_edges[0] = std::make_shared<Edge>(lb.x, lb.y, rt.x, lb.y);
// and so on

or use push_back to add elements:

this->_edges.reserve(4);

this->_edges.push_back(std::make_shared<Edge>(lb.x, lb.y, rt.x, lb.y));
// and so on

or assign from an initialiser list

this->_edges = {
    std::make_shared<Edge>(lb.x, lb.y, rt.x, lb.y),
    // and so on
};

or simplify the code to initialise it in the initialiser list, where such things belong

Box(const Point& lb, const Point& rt) :
    _edges {
        std::make_shared<Edge>(lb.x, lb.y, rt.x, lb.y),
        // and so on
    }
{}

Upvotes: 3

dlf
dlf

Reputation: 9373

vector::reserve reserves space but doesn't actually resize the array. Try using resize instead.

Upvotes: 1

Related Questions