Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does c++ std::vector work?

Tags:

c++

vector

How does adding and removing elements "rescale" the data? How is the size of the vector calculated (I believe it is kept track of)? Any other additional resources to learn about vectors would be appreciated.

like image 349
Alan Avatar asked Jul 02 '10 15:07

Alan


People also ask

How does a vector work in C++?

Vectors in C++ are sequence containers representing arrays that can change their size during runtime. They use contiguous storage locations for their elements just as efficiently as in arrays, which means that their elements can also be accessed using offsets on regular pointers to its elements.

Does std::vector use heap?

As mentioned above, std::vector is a templated class that represents dynamic arrays. std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.

What is the difference between std :: string and std::vector?

std::string offers a very different and much expanded interface compared to std::vector<> . While the latter is just a boring old sequence of elements, the former is actually designed to represent a string and therefore offers an assortment of string-related convenience functions.

Is std::vector fast?

A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.


2 Answers

In terms of sizing, there are two values of interest for a std::vector: size, and capacity (accessed via .size() and .capacity()).

.size() is the number of elements that are contained in the vector, whereas .capacity() is the number of elements that can be added to the vector, before memory will be re-allocated.

If you .push_back() an element, size will increase by one, up until you hit the capacity. Once the capacity is reached, most (all?) implementations, re-allocate memory, doubling the capacity.

You can reserve a capacity using .reserve(). For example:

std::vector<int> A; A.reserve(1);        // A: size:0, capacity:1  {[],x} A.push_back(0);      // A: size:1, capacity:1  {[0]} A.push_back(1);      // A: size:2, capacity:2  {[0,1]} A.push_back(2);      // A: size:3, capacity:4  {[0,1,2],x} A.push_back(3);      // A: size:4, capacity:4  {[0,1,2,3]} A.push_back(4);      // A: size:5, capacity:8  {[0,1,2,3,4],x,x,x} 

Reallocations of memory would occur at lines 4, 5, and 7.

like image 129
MarkD Avatar answered Oct 09 '22 21:10

MarkD


The vector usually has three pointers. If the vector has never been used they are all 0, or NULL.

  • One to the first element of the vector. (this is the begin() iterator)
  • One to last element of the vector + 1. (this is the end() iterator)
  • And one more to the last allocated but unused element + 1. (this minus begin() is the capacity)

When an element is inserted, the vector allocates some storage and sets its pointers. It might allocate 1 element, or it might allocate 4 elements. Or 50.

Then it inserts the element and increments the last element pointer.

When you insert more elements than are allocated the vector has to get more memory. It goes out and gets some. If the memory location changes then it has to copy all the elements into the new space and free the old space.

A common choice for resizing is to double the allocation every time it needs more memory.

like image 28
Zan Lynx Avatar answered Oct 09 '22 19:10

Zan Lynx