C++ Vectors

Dynamic arrays with automatic memory management

🚀 What are Vectors?

Vectors are dynamic arrays that can grow and shrink automatically. They provide random access to elements and efficient insertion at the end, making them versatile containers.


#include <vector>
using namespace std;

vector<int> numbers = {1, 2, 3};
numbers.push_back(4);
cout << numbers[0]; // Access by index
                                    

Output:

1

Vector Features

📏

Dynamic Size

Grows and shrinks automatically

vector<int> v;
v.push_back(10); // Size becomes 1
🎯

Random Access

Access elements by index

vector<int> v = {1,2,3};
cout << v[1]; // Prints 2
🔄

Iterators

Support for iterator-based loops

for(auto it = v.begin(); 
    it != v.end(); ++it)

Efficient

Fast insertion at end

v.push_back(value); // O(1)
v.pop_back(); // O(1)

🔹 Creating and Initializing Vectors

Vectors in C++ are dynamic arrays that can grow or shrink in size, offering multiple initialization methods for flexibility. You can create an empty vector, specify its initial size, fill it with default or specific values, or initialize it from another container or list. For example, using initializer lists ({1, 2, 3}) provides concise syntax, while the constructor allows setting size and default value. Understanding these methods helps optimize memory usage and performance from the start.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // Empty vector
    vector<int> v1;
    cout << "v1 size: " << v1.size() << endl;
    
    // Vector with size
    vector<int> v2(5); // 5 elements, all 0
    cout << "v2 size: " << v2.size() << endl;
    
    // Vector with size and value
    vector<int> v3(3, 10); // 3 elements, all 10
    cout << "v3: ";
    for(int x : v3) cout << x << " ";
    cout << endl;
    
    // Initialize with values
    vector<int> v4 = {1, 2, 3, 4, 5};
    cout << "v4: ";
    for(int x : v4) cout << x << " ";
    cout << endl;
    
    // Copy constructor
    vector<int> v5(v4);
    cout << "v5 (copy of v4): ";
    for(int x : v5) cout << x << " ";
    cout << endl;
    
    return 0;
}

Output:

v1 size: 0
v2 size: 5
v3: 10 10 10
v4: 1 2 3 4 5
v5 (copy of v4): 1 2 3 4 5

🔹 Vector Operations

C++ vectors support a comprehensive set of operations for efficient element management and data manipulation. Key functions include push_back and emplace_back for adding elements, insert for placing items at specific positions, and erase or pop_back for removal. You can access elements via at() (with bounds checking) or the [] operator. Additionally, methods like size(), capacity(), and empty() provide essential metadata for resource-aware programming.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {10, 20, 30};
    
    // Adding elements
    numbers.push_back(40);
    numbers.insert(numbers.begin() + 1, 15); // Insert 15 at index 1
    
    cout << "After insertions: ";
    for(int num : numbers) cout << num << " ";
    cout << endl;
    
    // Accessing elements
    cout << "First element: " << numbers.front() << endl;
    cout << "Last element: " << numbers.back() << endl;
    cout << "Element at index 2: " << numbers[2] << endl;
    cout << "Element at index 2 (safe): " << numbers.at(2) << endl;
    
    // Size information
    cout << "Size: " << numbers.size() << endl;
    cout << "Capacity: " << numbers.capacity() << endl;
    cout << "Empty: " << (numbers.empty() ? "Yes" : "No") << endl;
    
    // Removing elements
    numbers.pop_back(); // Remove last
    numbers.erase(numbers.begin() + 1); // Remove at index 1
    
    cout << "After removals: ";
    for(int num : numbers) cout << num << " ";
    cout << endl;
    
    return 0;
}

Output:

After insertions: 10 15 20 30 40
First element: 10
Last element: 40
Element at index 2: 20
Element at index 2 (safe): 20
Size: 5
Capacity: 8
Empty: No
After removals: 10 20 30

🔹 Iterating Through Vectors

Iterating over vector elements is fundamental, and C++ offers several idiomatic approaches for traversal. The range-based for loop is the most readable for simple access. Index-based loops provide direct positional control, while iterators (including begin()/end()) offer flexibility for use with STL algorithms. Using auto with iterators reduces verbosity. Each method has its use case, balancing readability, performance, and compatibility with other standard library functions.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<string> fruits = {"apple", "banana", "orange", "grape"};
    
    // Method 1: Range-based for loop (C++11)
    cout << "Method 1 - Range-based for: ";
    for(const string& fruit : fruits) {
        cout << fruit << " ";
    }
    cout << endl;
    
    // Method 2: Traditional for loop with index
    cout << "Method 2 - Index-based: ";
    for(size_t i = 0; i < fruits.size(); i++) {
        cout << fruits[i] << " ";
    }
    cout << endl;
    
    // Method 3: Iterator
    cout << "Method 3 - Iterator: ";
    for(auto it = fruits.begin(); it != fruits.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
    
    // Method 4: Auto with index
    cout << "Method 4 - Auto: ";
    for(auto fruit : fruits) {
        cout << fruit << " ";
    }
    cout << endl;
    
    return 0;
}

Output:

Method 1 - Range-based for: apple banana orange grape
Method 2 - Index-based: apple banana orange grape
Method 3 - Iterator: apple banana orange grape
Method 4 - Auto: apple banana orange grape

🔹 Practical Vector Example

Vectors are ideal for real-world applications like managing student grades, where dynamic data handling is required. You can store grades, compute statistics such as the average and maximum, and sort the list for analysis. Using algorithms like std::accumulate for sums, std::max_element for finding highs, and std::sort for ordering makes the code concise and efficient. This example demonstrates how vectors integrate seamlessly with the STL to solve common data-processing tasks.

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int main() {
    vector<double> grades;
    
    // Add some grades
    grades.push_back(85.5);
    grades.push_back(92.0);
    grades.push_back(78.5);
    grades.push_back(96.0);
    grades.push_back(88.5);
    
    cout << "Student Grades: ";
    for(double grade : grades) {
        cout << grade << " ";
    }
    cout << endl;
    
    // Calculate average
    double sum = accumulate(grades.begin(), grades.end(), 0.0);
    double average = sum / grades.size();
    cout << "Average: " << average << endl;
    
    // Find highest grade
    auto highest = *max_element(grades.begin(), grades.end());
    cout << "Highest grade: " << highest << endl;
    
    // Sort grades
    sort(grades.begin(), grades.end());
    cout << "Sorted grades: ";
    for(double grade : grades) {
        cout << grade << " ";
    }
    cout << endl;
    
    return 0;
}

Output:

Student Grades: 85.5 92 78.5 96 88.5
Average: 88
Highest grade: 96
Sorted grades: 78.5 85.5 88.5 92 96

🧠 Test Your Knowledge

Which function adds an element to the end of a vector?