How it works...

The std::vector class is designed to be the C++ container most similar to and inter-operable with C-like arrays. A vector is a variable-sized sequence of elements, guaranteed to be stored contiguously in memory, which makes the content of a vector easily passable to a C-like function that takes a pointer to an element of an array and, usually, a size. There are many benefits of using a vector instead of C-like arrays and these benefits include:

  • No direct memory management is required from the developer, as the container does this internally, allocating memory, reallocating, and releasing.
Note that a vector is intended for storing object instances. If you need to store pointers, do not store raw pointers but smart pointers. Otherwise, you need to handle the lifetime management of the pointed objects.
    • The possibility of modifying the size of the vector.
  • Simple assignment or concatenation of two vectors.
  • Direct comparison of two vectors.

The vector class is a very efficient container, with all implementations providing a lot of optimizations that most developers are not capable of doing with C-like arrays. Random access to its elements and insertion and removal at the end of a vector is a constant O(1) operation (provided that reallocation is not necessary), while insertion and removal anywhere else is a linear O(n) operation.

Compared to other standard containers, the vector has various benefits:

  • It is compatible with C-like arrays and C-like APIs; the content of other containers (except for std::array) needs to be copied to a vector before being passed to a C-like API expecting an array.
  • It has the fastest access to elements of all containers.
  • It has no per-element memory overhead for storing elements, as elements are stored in a contiguous space, like a C array (and unlike other containers such as list that requires additional pointers to other elements, or associative containers that require hash values).

std::vector is very similar in semantics to C-like arrays but has a variable size. The size of a vector can increase and decrease. There are two properties that define the size of a vector:

  • Capacity is the number of elements the vector can accommodate without performing additional memory allocations; this is indicated by the capacity() method.
  • Size is the actual number of elements in the vector; this is indicated by the size() method.

Size is always smaller or equal to capacity. When size is equal to capacity and a new element needs to be added, the capacity needs to be modified so that the vector has space for more elements. In this case, the vector allocates a new chunk of memory and moves the previous content to the new location and then frees the previously allocated memory. Though this sounds time-consuming (and it is), implementations increase the capacity exponentially, by doubling it each time it needs to be changed. As a result, on average, each element of the vector only needs to be moved once (that is because all the elements of the vector are moved during an increase of capacity, but then an equal number of elements can be added without incurring more moves, given that insertions are performed at the end of the vector).

If you know beforehand how many elements will be inserted in the vector, you can first call the reserve() method to increase the capacity to at least the specified amount (this method does nothing if the specified size is smaller than the current capacity) and only then insert the elements.

On the other hand, if you need to free additional reserved memory, you can use the shrink_to_fit() method to request this, but it is an implementation decision whether to free any memory or not. An alternative to this non-binding method, available since C++11, is to do a swap with a temporary, empty vector:

    std::vector<int> v{ 1, 2, 3, 4, 5 };
std::vector<int>().swap(v); // v.size = 0, v.capacity = 0

Calling the clear() method only removes all the elements from the vector but does not free any memory.

It should be noted that the vector implements operations specific to other types of containers:

  • stack: With push_back() and emplace_back() to add at the end and pop_back() to remove from the end. Keep in mind that pop_back() does not return the last element that has been removed. You need to access that explicitly, if that is necessary, for instance, using the back() method before removing the element.
  • list: With insert() and emplace() to add elements in the middle of the sequence and erase() to remove elements from anywhere in the sequence.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset