tags:

views:

427

answers:

4

Is there anything wrong with pushing back a vector of vectors? like

typedef vector<Point> Polygon;
vector<Polygon> polys;
polys.push_back(some_poly);

All the elements in some_poly will be copied right?

I have a bug in my code and I can't seem to figure out what's wrong with it.

+1  A: 

Nothing at all wrong with it. It's not the most efficient structure for inserts/erasures, but it should definitely work.

If you are interested in making inserts/erasures more efficient, you should probably switch to:

typedef vector<Point> Polygon;
typedef vector<Polygon*> Polygons;
Polygons polys;
polys.push_back(new Polygon());
Frank Krueger
But then you have to worry about resource management. You'll have to delete those pointers somehow when you are done.
Brian Neal
I dare say that the "Polygons" class should be the owner and can handle the deallocation. Resource management isn't so bad as long as you stick to clear ownership rules. But your point is valid.
Frank Krueger
+1  A: 

Yes, that should work fine, as long as you have defined a copy constructor and assignment operator for your Point class (and ensured they're doing the right thing etc). std::vector will push just fine, so the bug must be elsewhere - obviously we'd need more details to help further.

There are performance implications if you're going to push a vector of things, but don't worry about that until it's working (and then only if it becomes a problem).

Peter
The Polygon "class" (actually a typedef) already has a good copy constructor. You probably mean the Point class.
ahy1
Yes, I did. Thanks for that - have corrected :-)
Peter
+5  A: 

Right, the vector is copied like expected. There is a good software called geordi which can show this:

{ 
    using namespace tracked; 
    typedef vector<B> poly_t; 
    poly_t poly(3); // contains 3 B's
    vector<poly_t> v; 
    v.push_back(poly); 
}

It tracks creation/copies of tracked::B. Here is the output:

B0* B1*(B0) B2*(B0) B3*(B0) B0~ B4*(B1) B5*(B2) B6*(B3) B4~ B5~ B6~ B1~ B2~ B3~

This is output when we only track v.push_back:

B4*(B1) B5*(B2) B6*(B3)

As you see, first B0 is created as the default argument of the vector constructor. Then that object is copied into 3 B's and after that B0 is destroyed again as the constructor comes back. poly then is created. Then, we push_back it into a vector of polygons. The argument, poly, is copied into a new vector which is created within the vector of polygons and managed by that.

If it crashes, the problem probably lies within another part of your program. Checks that the copy constructor/constructor and destructor work correctly and that they don't delete things twice if you use dynamic memory allocation.

Johannes Schaub - litb
Thank you for the thorough reply! It must be a logic bug then. The wrong elements are getting copied, but that's another question.
Mark
A: 

Although there is nothing wrong with a vector of vectors, you might want to have a look at Boost.MultiArray. It can be more efficient.

 typedef boost::multi_array<Point, 2> Polygons;

Another idea is that you may want to make Polygon a real class (probably containing a vector) to provide more adapted methods than the ones provided by default with std::vector.

Benoît