user2381422
user2381422

Reputation: 5805

Adding objects to vectors vs adding pointers to vectors in c++?

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

Answers (6)

Apoorva sahay
Apoorva sahay

Reputation: 1930

I think the second approach of using vector of pointers is a better of the two options. Because of two simple reasons

  1. If the objects size are bigger then using vector of objects will add unnecessary copying.
  2. If you are passing the vector of objects as argument to a method and then try to modify any object in the vector then it will not get reflected at all the places.

Upvotes: -1

Taylor Brandstetter
Taylor Brandstetter

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

Steven Maitlall
Steven Maitlall

Reputation: 787

It really comes down to

  • What operations are going to be performed on that vector
  • How frequently objects will be pushed onto the vector

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Bathsheba
Bathsheba

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

Photon
Photon

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

Related Questions