C++ vectors


Introduction

In C++, a vector is a sequence container that stores elements in a dynamically allocated array. Unlike arrays, vectors can grow or shrink in size dynamically at runtime. Vectors are part of the C++ Standard Library and provide a more flexible and efficient way to handle collections of data compared to traditional arrays. They are defined in the <vector> header.

Vectors are commonly used in C++ because they allow:

  • Dynamic resizing.
  • Fast random access to elements.
  • Support for a wide range of member functions for manipulating and accessing data.

Key Features of Vectors

  • Dynamic Sizing: Vectors automatically resize when elements are added or removed, unlike arrays, where the size is fixed at compile time.
  • Efficient Access: Vectors provide constant time random access to elements (i.e., accessing elements via an index).
  • Contiguous Memory: Vectors store elements in a contiguous block of memory, just like arrays. This allows efficient memory usage and cache locality.
  • Standard Library Support: Vectors work seamlessly with other STL algorithms, making them versatile and easy to use.
  • Flexible Growth: As elements are added, the vector's size automatically increases, allocating more memory as needed.

Syntax

std::vector<T> vector_name;
  • T: The type of the elements (e.g., int, float, std::string).
  • The size of the vector is dynamic, so you don’t need to specify it at declaration.

You can also define a vector with an initial size:

std::vector<T> vector_name(size);

Where size is the number of elements initialized to default values.


Declaring and Initializing Vectors

Example 1: Basic Vector Declaration

#include <iostream>
#include <vector>

int main() {
    // Declare a vector of integers
    std::vector<int> v;

    // Adding elements to the vector
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);

    // Displaying elements using a range-based for loop
    for (int i : v) {
        std::cout << i << " ";
    }

    return 0;
}

Explanation:

  • push_back() adds elements to the end of the vector.
  • The range-based for loop is used to iterate through and display vector elements.

Example 2: Vector with Initial Values

#include <iostream>
#include <vector>

int main() {
    // Declare a vector of integers with initial values
    std::vector<int> v = {1, 2, 3, 4, 5};

    // Display elements using a range-based for loop
    for (int i : v) {
        std::cout << i << " ";
    }

    return 0;
}

Explanation:

  • The vector v is initialized with values {1, 2, 3, 4, 5}.

Important Member Functions of Vectors

std::vector provides several useful member functions to work with vectors:

1. push_back()

Adds an element to the end of the vector.

std::vector<int> v = {1, 2, 3};
v.push_back(4);  // Adds 4 to the end of the vector

2. size()

Returns the number of elements in the vector.

std::cout << "Size of vector: " << v.size() << std::endl;

3. empty()

Checks if the vector is empty.

if (v.empty()) {
    std::cout << "The vector is empty!" << std::endl;
} else {
    std::cout << "The vector is not empty!" << std::endl;
}

4. at()

Accesses an element with bounds checking.

std::cout << "Element at index 2: " << v.at(2) << std::endl;

Note: Unlike the [] operator, at() throws an std::out_of_range exception if the index is out of bounds.

5. front() and back()

Access the first and last elements of the vector, respectively.

std::cout << "First element: " << v.front() << std::endl;  // Output: 1
std::cout << "Last element: " << v.back() << std::endl;  // Output: 4

6. pop_back()

Removes the last element from the vector.

v.pop_back();  // Removes 4 from the vector

7. clear()

Removes all elements from the vector, leaving it empty.

v.clear();  // The vector is now empty

8. resize()

Resizes the vector to a new size. If the new size is larger, new elements are initialized to their default values.

v.resize(7);  // Resize the vector to 7 elements

Iterating Through Vectors

You can iterate over a vector using different methods, such as traditional loops, range-based for loops, or iterators.

Example 1: Using a Traditional for Loop

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v = {10, 20, 30, 40};

    // Traditional for loop
    for (size_t i = 0; i < v.size(); ++i) {
        std::cout << v[i] << " ";
    }

    return 0;
}

Example 2: Using Range-Based for Loop

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};

    // Range-based for loop
    for (int i : v) {
        std::cout << i << " ";
    }

    return 0;
}

Example 3: Using Iterators

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v = {5, 10, 15};

    // Using iterators to traverse the vector
    for (auto it = v.begin(); it != v.end(); ++it) {
        std::cout << *it << " ";
    }

    return 0;
}

Advantages of Vectors Over Arrays

  1. Dynamic Sizing: Unlike arrays, vectors can dynamically resize, allowing them to accommodate a variable number of elements.
  2. Memory Management: Vectors automatically manage memory for you, resizing as needed, which prevents issues like memory overflow or underutilization.
  3. Efficiency: Vectors provide fast access and insertion/removal at the end of the container, making them more efficient than using arrays in certain use cases.
  4. Compatibility with STL Algorithms: Vectors are compatible with many of the standard C++ algorithms, such as std::sort, std::find, etc.

When to Use Vectors

Use vectors when:

  • You need a dynamically sized collection of elements.
  • You need random access to elements by index.
  • You need to frequently add or remove elements at the end of the collection.
  • You want to use STL algorithms with your data.