2

Suppose I have complex objects, like structs containing a huge amount of members - and I want to store them in a vector.

Now vector::push_back(...) works over call-by-reference (rather than call-by-value), so in the first moment the passed object is not copied. But what about later? Does a vector internally store pointers or direct references? When the vector needs to expand, are the contained elements themselves copied or their addresses?

This finally results in the question, if - for large objects - the objects themselves should be stored in a vector or rather pointers to these objects. Is there a kind of best practice for that?

aRestless
  • 1,825
  • 2
  • 18
  • 27
  • possible dupilcate of http://stackoverflow.com/questions/6349322/how-does-stdvector-copy-objects-to-its-internal-storage `` uses your objects copy constructor so make sure you define one – Stephen O'Connor Nov 24 '11 at 15:10

3 Answers3

3

std::vector::push_back saves copy of the object.

If you need performance by avoiding copy, then you could use vector of pointers.

std::vector<BigObject*> objects; //manage memory yourself

Or you can use some sort of smart pointer, so as to avoid managing memory yourself. For example, you could use std::unique_ptr if your compiler supports it:

std::vector<std::unique_ptr<BigObject>> objects;

If you use pointers (or smart pointers), then copying is still there, but this time, the copy is done for pointers (or smart pointers) which is much cheaper.

From @Loki's comment:

Or you can use boost::ptr_vector<> which is designed to hold pointers and will return references when accesses thus makeing it easy to use standard algorithms as they all expect objects.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • it is probably better a shared_ptr instead of a naked one in your first example – Alessandro Teruzzi Nov 24 '11 at 15:12
  • 3
    If the objects are not owned then pointers are fine, but I would prefer to use boost::ptr_vector<> (rather than a vector os smart pointers) as it is designed to hold pointers and will return references when accesses thus making it easy to use standard algorithms as they all expect objects. – Martin York Nov 24 '11 at 15:23
  • 2
    +1 For the `unique_ptr` and not spamming everything with `shared_ptr`s all over the place like most people like to do. – Christian Rau Nov 24 '11 at 15:24
2

vector::push_back(...) works over call-by-reference (rather than call-by-value), so in the first moment the passed object is not copied

vector::push_back() stores the copy of the object being added to it.

Does a vector internally store pointers or direct references?

How a vector internally stores elements is an implementation detail but the complexity and the behavior requirements leave little room for variation. Vector stores the elements in a contiguous memory locations much like arrays.

When the vector needs to expand, are the contained elements themselves copied or their addresses?

When a vector expands, it needs to copy all the objects to a new contiguous memory, again this is a implementation detail. If elements are pointers then the pointers themselves will be copied.

The objects themselves should be stored in a vector or rather pointers to these objects. Is there a kind of best practice for that?

If your objects are bigger and you do not want to place them in a vector then you can store pointers to them in the vector but then do not store raw pointers in vector, use a suitable smart pointer as per your requirement. It ensures perfect RAII and you do not need to be bothered about the memory management explcitily.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

Actually, if you're iterating over the vector more than you're adding objects to it, you will greatly outperform pointer by adding objects, as they will be contiguous in memory.

However if you're doing more adding and erasing to and from the vector, than you are iterating over it, pointers will be more efficient.

metamorphosis
  • 1,972
  • 16
  • 25