views:

394

answers:

2

Hi,

I've always been a bit confused about how STL containers (vector, list, map...) store values. Do they store references to the values I pass in, or do they copy/copy construct +store the values themselves?

For example,

int i;
vector<int> vec;
vec.push_back(i);
// does &(vec[0]) == &i;

and

class abc;
abc inst;
vector<abc> vec;
vec.push_back(inst);
// does &(vec[0]) == &inst;

Thanks

+10  A: 

STL Containers copy-construct and store values that you pass in. If you want to store objects in a container without copying them, I would suggest storing a pointer to the object in the container:

class abc;
abc inst;
vector<abc *> vec;
vec.push_back(&inst);

This is the most logical way to implement the container classes to prevent accidentally storing references to variables on defunct stack frames. Consider:

class Widget {
public:
    void AddToVector(int i) {
        v.push_back(i);
    }
private:
    vector<int> v;
};

Storing a reference to i would be dangerous as you would be referencing the memory location of a local variable after returning from the method in which it was defined.

Mike Koval
You cannot create create containers that store references in C++. The type argument passed to the container must be assignable. References are not assignable, they are initialized with an object but cannot be assigned to a refer a different object after construction. Thus reference types do not fulfill the type requirements to be used inside containers. If you want to have the same semantics (or as close as it gets) you must provide a reference wrapper (boost::ref/boost::cref)
David Rodríguez - dribeas
@dribeas: This answer explains _why not_, by explaining the risks of a hypothetical implementation.
MSalters
+2  A: 

That depends on your type. If it's a simple value type, and cheap to copy, then storing values is probably the answer. On the other hand, if it's a reference type, or expensive to copy, you'd better store a smart pointer (not auto_ptr, since its special copy semantics prevent it from being stored in a container. Go for a shared_ptr). With a plain pointer you're risking memory leakage and access to freed memory, while with references you're risking the latter. A smart pointer avoids both.

On Freund
+1 on the use of smart pointers inside containers to deal with memory. Another choice could be using a library like Boost Pointer Container to take care of resource deallocation
David Rodríguez - dribeas
That's not what the OP is asking about. He wants to know if the container classes themselves copy the value when when it is placed in the container. The answer is, yes, they do -- which is why storing pointers can be good if the particular type in question is expensive to copy.
Dan Moulding
And storing naked pointers is perfectly fine if you know what you are doing and clean up after yourself.
Brian Neal