Search code examples
c++vectornew-operator

Why use a new call with a C++ 'vector'?


The code vector<someType> myVector; dynamically allocates memory, so any elements stored will live until a delete is called. So how is the following, vector<someType> *myVector = new vector<someType>();, different (other than being a pointer) from the earlier one?

Is there a double allocation happening here? Everyone mentions it is evil to mix a vector with a new call, but why? If it is evil, why is it acceptable code for the compiler and when is it okay to use?


Solution

  • Your first statement is not true. The elements in vector<someType> myVector will live until the vector is destroyed. If vector<someType> is a local variable, it will be destroyed automatically when it goes out of scope. You don't need to call delete explicitly. Calling delete explicitly is error-prone if you take into account that because of exceptions that might be thrown, your delete statement may never be reached, leading to memory leaks. E.g. compare the following two cases

    void foo()
    {
       std::vector<int> v;
       v.push_back(1);
       f(); // f is some operation that might throw exception.
    }  // v is automatically destroyed even if f throws.
    
    void bar()
    {
       std::vector<int>* v = new std::vector<int>;
       v->push_back(1);
       f(); // f is some operation that might throw exception.
       delete v;  // You need to call delete explicitly here.
                  // The vector will be destroyed only if f doesn't throw.
    }
    

    Apart from the above, it's true that a vector dynamically allocates memory to store new elements. The difference between the two cases is:

    • std::vector<int> v v is an object on the stack, that dynamically allocates memory in order to store elements.

    • std::vector<int>* v = new std::vector<int> v is a pointer to a dynamically allocated object, that dynamically allocates memory in order to store elements. As said already, you need to explictly call delete to destroy this object.