Search code examples
c++vectorshared-ptr

Arrays and smart pointers


1.1) Is there a possibility of a memory leak when using std::vector, QVector, boost::array (not quite understand the difference between them in the use of memory and what are the advantages of each)? Or they follow the memory as smart pointers?

1.2) Or is it better to create them through a shared_ptr?

2) What better shared_aray or shared_ptr + vector?


Solution

  • There is no possibility of memory leak in either of those three in the memory they manage. That is, the data stored in a std::vector, QVector or std::array will be correctly deallocated when the container is destroyed.

    On the other hand, if you manage the container itself in an unsafe way, you can of course leak the entire container. E.g. if you do something like new std::vector<int>() and later leak the pointer which new gave you. Note that there is very rarely reason to allocate containers dynamically.

    Also, if you store unsafe pointers in the containers, you can of course leak what such pointers point to.

    As for the difference between the containers you listed:

    • std::vector holds a contiguous array of memory, and it is capable of growing dynamically when it needs more space. Each such growth involves allocating larger space and moving the currently stored elements into the new space, then deallocating the old one.

    • QVector is a weird beast, similar a bit to std::deque. Internally, it's implemented as if it was a vector of pointers. That is, you won't be too far off if you think of QVector<T> as equivalent to std::vector<std::unique_ptr<T>>, for T larger than a pointer, and std::vector<T> for T pointer-sized or smaller.

    • std::array is fundamentally different from the above two in that it doesn't hold dynamic memory, and cannot grow dynamically. std::array<T, N> is just a very thin wrapper around T [N], giving it a container-like interface.

    Regarding your question 2, each is different again: a shared_array cannot grow once it's allocated, std::vector can. There is very rarely a reason to store std::vector in a smart pointer (or any pointer), since it's rare to allocate it dynamically in the first place.