Vectors in C++

Filed Under: C++
Cpp Vector

A Vectors in C++ is an array-like container that can change dynamically in size. Being a part of the C++ STL, a Vector can support various dynamic array operations.


Overview of Vectors in C++

Vectors, being similar to arrays, are stored in contiguous memory locations. This means that the access time is very quick.

Vectors use a dynamically allocated array, which means that it must be reallocated if it ever reaches its limit.

This reallocation operation is a bit expensive, which is the one disadvantage of Vectors.

The below image shows a scenario where the Vector reallocation occurs.

The original vector (<1, 2>) with a capacity of 2, is now resized dynamically to a capacity of 4 before a third element can be added to the now-empty locations.

Vector Reallocation
Vector Reallocation

Create a Vector in C++

To use this container, we must first include the header file vector.

#include <vector>

We can now create a new vector using :

std::vector<type> a;

Here, <type> can refer to any data type, such as int, float, char, etc.

We can also directly assign elements during initialization.

#include <vector>

using namespace std;

vector<int> a = {1, 2, 3, 4};

This will create an integer vector initialized to <1, 2, 3, 4>. So the first element is 1, and the last element is 4.

Now that we have our vector, let’s look at some of the vector operations involving it.


Vector operations in C++

There are various methods that we can use on the vector container, some of them being:

Iterator Methods

  • begin() -> Returns an iterator to the beginning
  • end() -> Returns an iterator to the end
  • rbegin() -> Returns a reverse iterator to the reverse beginning
  • rend() -> Returns a reverse iterator to the reverse end

Here is an example showing the above methods. We cannot directly print a vector using cout, and must access elements of a vector in a for loop.

Iterators can be used for this purpose.

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> a = {1, 2, 3, 4};
    for (auto it = a.begin(); it != a.end(); it++)
        cout << *it << " ";
    return 0;
}

Output

1 2 3 4 

Similarly, we can print the vector in reverse, using rbegin() and rend().

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> a = {1, 2, 3, 4};
    for (auto it = a.rbegin(); it != a.rend(); it++)
        cout << *it << " ";
    return 0;
}

Output

4 3 2 1 

Capacity methods

  • size() -> Returns the size
  • max_size() -> Returns the maximum size that can be allocated
  • resize(SIZE) -> Resizes the vector to SIZE elements
  • capacity() -> Returns the size of the allocated memory capacity
  • empty() -> Checks if the vector is empty
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> a = {1, 2, 3, 4, 5, 6};

    for (auto it = a.begin(); it != a.end(); it++)
        cout << *it << " ";
    cout << endl;
    
    cout << "Is the vector empty? " << (a.empty() ? "Yes" : "No") << endl;
    cout << "Size: " << a.size() << endl;
    cout << "Capacity: " << a.capacity() << endl;
    cout << "Maximum Size: " << a.max_size() << endl;

    // Let's resize the vector to 4
    a.resize(4);
    
    cout << "Vector after resize(): \n";

    for (auto it = a.begin(); it != a.end(); it++)
        cout << *it << " ";
    
    cout << endl;

    return 0;
}

Output

1 2 3 4 5 6 
Is the vector empty? No
Size: 6
Capacity: 6
Maximum Size: 2305843009213693951
Vector after resize(): 
1 2 3 4 

Element Access methods

  • Using [] operator. Same as for arrays.
  • at(INDEX) -> Access an element at position INDEX
  • front() -> Access the first element
  • back() -> Access the last element
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> a = {1, 2, 3, 4, 5, 6};

    cout << "Access using []:\n";
    for (unsigned int i=0; i<a.size(); i++)
        cout << a[i] << " ";
    cout << endl;

    cout << "Access using at():\n";
    for (unsigned int i=0; i<a.size(); i++)
        cout << a.at(i) << " ";
    cout << endl;

    cout << "First Element: " << a.front() << endl;
    cout << "Last Element: " << a.back() << endl;

    return 0;
}

Output

Access using []:
1 2 3 4 5 6 
Access using at():
1 2 3 4 5 6 
First Element: 1
Last Element: 6

Modifier methods

  • push_back() -> Add element at the end
  • pop_back() -> Delete the last element
  • clear() -> Clear content
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> a = {1, 2, 3, 4, 5, 6};

    a.push_back(7);
    a.push_back(8);

    cout << "vector after push_back():\n";
    for(unsigned int i=0; i<a.size(); i++)
        cout << a[i] << " ";
    cout << endl;
    

    a.pop_back();

    cout << "vector after pop_back():\n";
    for(unsigned int i=0; i<a.size(); i++)
        cout << a[i] << " ";

    return 0;
}

As you can see, we do some push and pop operations on the vector to dynamically change the size. This shows the dynamic nature of vectors.

vector after push_back():
1 2 3 4 5 6 7 8 
vector after pop_back():
1 2 3 4 5 6 7

References


Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages