Reputation: 5805
Adding objects to vectors vs adding pointers to vectors in c++.
Example:
std::vector<Size> buildings;
Size building(buildingWidth, buildingHeight);
buildings.push_back(building);
VS
std::vector<Size*> buildings;
Size *building = new Size(buildingWidth, buildingHeight);
buildings.push_back(building);
Which one is better in terms of memory/performance?
The first one basically creates an object on the stack and adds it to a vector. So there is one instantiation followed by one copy into the vector.
The second one creates an object on the heap. There is one instantiation, but there is no copy into the vector.
Am I correct?
Upvotes: 3
Views: 210
Reputation: 1930
I think the second approach of using vector of pointers is a better of the two options. Because of two simple reasons
Upvotes: -1
Reputation: 3623
Why not do this:
std::vector<Size> buildings;
buildings.resize(1);
buildings[0].setSize(buildingWidth, buildingHeight);
This way the constructor is only called once, and you don't have to manage the memory yourself. The only disadvantage I can think of is that the width and height are set twice (once in constructor, once in "setSize"), but I don't think you can get away from that unless you use the std::vector<Size *>
approach.
Upvotes: 0
Reputation: 787
It really comes down to
If you're going to be doing any kind of mutable operation on the vector, then you'd better go with a shared_ptr type.
Ultimately, with any kind of performance-related question, it's best to test it out yourself under the conditions of your application.
Upvotes: 0
Reputation: 727137
The two storage techniques serve different purposes.
The first technique is useful with "homogenous" vectors, where you do not need polymorphic behavior, and object slicing is not an issue. You get automated resource management in return: you do not need to worry about the ownership of your objects, because the vector makes a copy. A copy is also made internally every time your vector is resized. This consideration makes the first option less attractive when copying the object is somewhat expensive; you need to profile your code to see if this consideration applies to it.
The second technique puts the responsibility for managing the memory on you: every time you decide to remove an object from your vector of pointers, you need to take the ownership, and eventually delete
the object explicitly. You can use smart pointers to address the resource management issue. This technique lets you avoid copying, but the process of accessing elements inside the container becomes slightly more involved.
Upvotes: 4
Reputation: 234885
It really depends on the nature of Size. If the object is big (insofar that the copy constructor has to do a lot of work), then you could consider your pointer idea. However you will have to control the memory yourself and, whatever you do, don't inherit from std::vector as inheriting from the standard containers is not a good idea (for one thing they don't have virtual destructors)!
You could build some copy on write semantics in your Size class (a bit like implementations of std::string).
Or have a default constructor and a swap method for Size (you'll need the default constructor to be used in std::vector anyway). Use the swap method to swap in a new Size object into the position in the vector.
On the basis that "premature optimisation is the root of all evil" (attrib. Tony Hoare), I'd stick with the simplest approach; namely your first idea and see how that goes.
Upvotes: 0
Reputation: 3222
They both usually have relatively similar performance, depending on the object size and copy semantics of the object. With regards to memory leaks and usability, the first way is usually much better.
Upvotes: 0