Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🔴 Advanced  ·  Lesson 54

Vector in C++ STL

In this lesson: Use std::vector in C++ — push_back, size, insert, erase, capacity — with examples and output. In Hindi & English.

What Is std::vector in C++?

std::vector<T> is the standard growable sequence container. For ordinary element types, it stores elements contiguously like an array, but manages storage and lifetime automatically. Its size can change at runtime.

#include <vector>

std::vector<int> marks{78, 91, 84};
PropertyVector guarantee
Indexed accessConstant time
Insert/erase at endAmortized constant time for insertion
Insert/erase in middleLinear time
StorageContiguous for T other than bool
OwnershipElements and storage released automatically
Best default: when you need a general growable sequence, begin with vector unless a measured requirement demands different ordering, insertion or handle-stability guarantees.

Use std::array for a fixed compile-time size and std::deque when efficient operations at both ends are essential. For the wider decision, see vector versus map.

Creating and Initializing Vectors

std::vector<int> empty;                 // size 0
std::vector<int> five_zeros(5);         // 0 0 0 0 0
std::vector<int> four_sevens(4, 7);     // 7 7 7 7
std::vector<int> values{5, 10, 15};     // initializer list
std::vector copy = values;              // class template deduction
std::vector<int> part(values.begin(), values.begin() + 2);

Parentheses and braces mean different things. vector<int>(5, 10) contains five copies of 10, while vector<int>{5, 10} contains two elements: 5 and 10.

A vector owns values, not references. Store a lightweight record type rather than parallel vectors that can become misaligned:

struct Student {
    std::string name;
    int mark;
};

std::vector<Student> students{{"Aman", 78}, {"Sara", 91}};

Include every directly used header, here <vector> and <string>. Avoid using namespace std; in headers and teaching examples.

Safe Element Access

OperationUseEmpty/out-of-range behavior
v[i]Known-valid indexNo bounds check
v.at(i)Checked indexThrows std::out_of_range
v.front()First elementRequires non-empty vector
v.back()Last elementRequires non-empty vector
v.data()Pointer to contiguous rangeDo not dereference for empty range
if (!marks.empty()) {
    std::cout << marks.front() << ' ' << marks.back();
}

try {
    std::cout << marks.at(user_index);
} catch (const std::out_of_range&) {
    std::cerr << "Invalid index\n";
}

Use std::size_t or an appropriate container size type for indexes. When reverse loops are needed, avoid unsigned underflow; reverse iterators are often clearer.

Essential Vector Methods

MethodEffect
push_back(value)Copy/move a value to the end
emplace_back(args...)Construct an element at the end
pop_back()Remove last element; vector must not be empty
insert(pos, value)Insert before an iterator position
erase(pos/range)Remove one element or a range
clear()Destroy all elements; capacity need not shrink
assign(...)Replace the contents
swap(other)Exchange contents and capacity
marks.push_back(96);
marks.emplace_back(88);
marks.insert(marks.begin() + 1, 80);
marks.erase(marks.begin() + 2);

// C++20: remove every failing mark and return count removed
const auto removed = std::erase_if(marks, [](int m) { return m < 40; });

pop_back() returns nothing. Read back() first if you need the value. Prefer emplace_back when constructor arguments are available, but do not assume it is automatically faster than moving an already-created object.

Size, Capacity, reserve and resize

std::vector<int> values;
values.reserve(100);  // capacity at least 100, size still 0
values.push_back(7);  // size becomes 1
values.resize(4);     // size 4: appends three value-initialized zeros
MemberMeaning
size()Number of live elements
capacity()Elements current storage can hold before reallocation
reserve(n)Request capacity of at least n; size unchanged
resize(n)Change number of elements
shrink_to_fit()Non-binding request to reduce capacity
Classic error: after reserve(100), values[50] is invalid because capacity is not size. Add elements or resize before indexing.

Reserve when a reliable approximate final size is known. Calling reserve before every push_back can defeat geometric growth and worsen performance. Growth factor is implementation-specific; write against the capacity guarantee, not an assumed doubling rule.

Iteration, Algorithms and Invalidation

for (int mark : marks) {                 // copy each int
    std::cout << mark << ' ';
}

for (const Student& student : students) { // no record copy
    std::cout << student.name << '\n';
}

std::sort(marks.begin(), marks.end());

Vector iterators are random-access and contiguous iterators, so standard algorithms such as sort, binary_search and lower_bound work efficiently when their preconditions are met.

  • Reallocation invalidates every iterator, pointer and reference to elements, including the past-the-end iterator.
  • If insertion does not reallocate, handles before the insertion position remain valid; those at or after it are invalidated.
  • Erase invalidates handles at or after the erased position.
  • reserve invalidates handles only if it reallocates.
auto it = marks.begin();
marks.push_back(99); // it may now be invalid
it = marks.begin();  // reacquire before use

Continue with iterators and STL algorithms.

Complete Practical Program with Verified Output

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<int> marks;
    marks.reserve(6);
    for (int mark : {72, 88, 65, 91, 88}) {
        marks.push_back(mark);
    }

    const int total = std::accumulate(marks.begin(), marks.end(), 0);
    const auto highest = *std::max_element(marks.begin(), marks.end());
    std::sort(marks.begin(), marks.end());

    std::cout << "Sorted:";
    for (int mark : marks) std::cout << ' ' << mark;
    std::cout << std::fixed << std::setprecision(1)
              << "\nAverage: " << total / static_cast<double>(marks.size())
              << "\nHighest: " << highest;
}
Sorted: 65 72 88 88 91 Average: 80.8 Highest: 91

The vector owns five integers. Reserving six positions avoids reallocation during these insertions but creates no elements. The average uses floating-point division; integer division would incorrectly discard the decimal part.

Common Mistakes, Practice and Review

MistakeCorrection
Index equals size()Last valid index is size()-1 for non-empty vector
Indexing after reserve onlypush/resize first
Calling front/back/pop on empty vectorCheck empty()
Keeping iterator across growthReacquire after possible reallocation
Expecting clear to free capacityCapacity may remain for reuse
Using vector of raw owning pointersStore values or owning smart pointers
Parallel vectors for one recordUse vector<Record>

Practice: (1) remove duplicate marks using sort–unique–erase, (2) store Student records and sort by descending mark, (3) demonstrate size/capacity before and after reserve, (4) erase all negative values safely, and (5) compare checked at() with [].

  1. Did you include <vector> directly?
  2. Is the index provably valid?
  3. Are empty-container preconditions handled?
  4. Is capacity being confused with size?
  5. Could mutation invalidate a saved handle?
  6. Are algorithms given valid ranges and preconditions?

Authoritative References

Storage, complexity, reserve/resize and invalidation statements were checked against the current working draft. For STL architecture, read the complete STL guide.

Frequently Asked Questions

What is a vector in C++?
std::vector is an allocator-aware sequence container whose elements, except for the vector specialization, are stored contiguously. It supports constant-time indexed access and amortized constant-time insertion at the end.
What is the difference between vector size and capacity?
size is the number of constructed elements. capacity is how many elements the current storage can hold before reallocation is required. Capacity can be greater than size.
What is the difference between reserve and resize?
reserve requests storage capacity without creating elements or changing size. resize changes the number of elements, constructing new elements or removing trailing ones.
Should I use vector operator[] or at()?
operator[] has no bounds check. at() checks the index and throws std::out_of_range when invalid. Use at() when invalid input must be detected; ensure a proven valid index in performance-sensitive code.
When does a vector invalidate iterators and references?
A reallocation invalidates all element iterators, pointers and references. Without reallocation, insertion invalidates handles at or after the insertion point; erase invalidates handles at or after the erased position.
← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topiclist and deque in STL Your progress: 54 / 81 (67%) · Lesson 55 / 81 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free