Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is using vector of pointers considered bad?

Recently I've met with opinion that I shouldn't use vector of pointers. I wanted to know - why I cant?

For example if I have a class foo it is possible to do this:

vector <foo*> v;
v.push_back(new foo());

I've already seen some people down voting such practices, why is that?

like image 722
Patryk Krawczyk Avatar asked Dec 13 '14 15:12

Patryk Krawczyk


People also ask

Why the usage of pointers in C++ is not recommended?

It is best to avoid using pointers in C++ as much as possible. The use of pointers can lead to confusion of ownership which can directly or indirectly lead to memory leaks. Even if object ownership is well managed simple (and difficult to find) bugs can also lead to memory leaks.

Can you have a vector of pointers?

You can store pointers in a vector just like you would anything else. Declare a vector of pointers like this: vector<MyClass*> vec; The important thing to remember is that a vector stores values without regard for what those values represent.

What is the main issue with storing objects in the vector class as opposed to pointers?

Having vector of objects is much slower than a vector of pointers. The results are because algorithms such as sorting need to move elements inside the container. So they not only read the data but also perform a copy (when the algorithm decides to swap items or move to a correct place according to the order).

Why pointer is bad?

Smart pointers typically keep track of the objects they point to for the purpose of memory management. The misuse of pointers is a major source of bugs: the constant allocation, deallocation and referencing that must be performed by a program written using pointers introduces the risk that memory leaks will occur.


1 Answers

Using an vector of raw pointers is not necessary bad style, as long as you remember that the pointers do not have ownership semantics. When you start using new and delete, it usually means that you're doing something wrong.

In particular, the only cases where you should use new or delete in modern C++ code is when constructing unique_ptr's, or constructing shared_ptr's with custom deleters.

For example, assume that we have an class that implemented an bidirectional Graph, a Graph contains some amount of Vertexes.

class Vertex 
{
public: 
    Vertex();
    // raw pointer. No ownership
    std::vector<Vertex *> edges;
}

class Graph 
{
public:
    Graph() {};

    void addNode() 
    {
        vertexes.push_back(new Vertex); // in C++14: prefer std::make_unique<>
    }

// not shown: our Graph class implements a method to traverse over it's nodes
private:
    // unique_ptr. Explicit ownership
    std::vector<std::unique_ptr<Vertex>> vertexes;
}

void connect(Vertex *a, Vertex *b) 
{
    a->edges.push_back(b);  
    b->edges.push_back(a);
}

Notice how i have an vector of raw Vertex * in that Vertex class? I can do that because the lifetime of the Vertexes that it points to are managed by the class Graph. The ownership of my Vertex class is explicit from just looking at the code.

An different answer suggests using shared_ptr's. I personally dislike that approach because shared pointers, in general, make it very hard to reason about the lifetime of objects. In this particular example, shared pointers would not have worked at all because of the circular references between the Vertexes.

like image 184
Stefan Avatar answered Sep 27 '22 17:09

Stefan