Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
🔴 Advanced  ·  Lesson 54

Vector in C++ STL

Written and reviewed by · Senior IT Faculty · 15+ years’ experience

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.

C++ में std::vector क्या है?

std::vector<T> growable sequence container है। Ordinary types में elements contiguous रहते हैं, array जैसी indexing मिलती है और memory/lifetime automatic manage होती है।

#include <vector>
std::vector<int> marks{78,91,84};
PropertyGuarantee
Index accessO(1)
End insertionAmortized O(1)
Middle insert/eraseO(n)
Storagevector<bool> छोड़कर contiguous
General growable sequence में vector से start करें, जब तक ordering/insertion/handle stability की requirement दूसरा container न मांगे। vector vs map भी देखें।

Vector Create और Initialize करें

std::vector<int> empty;
std::vector<int> five_zeros(5);
std::vector<int> four_sevens(4,7);
std::vector<int> values{5,10,15};
std::vector copy=values;

vector<int>(5,10) पांच बार 10 रखता है, जबकि {5,10} दो values रखता है। Related fields के parallel vectors के बजाय record रखें:

struct Student{std::string name;int mark;};
std::vector<Student> students{{"Aman",78},{"Sara",91}};

Direct headers include करें और headers/examples में using namespace std; avoid करें।

Elements Safely Access करें

MethodUse
v[i]No bounds check
v.at(i)Invalid पर out_of_range
front()First, vector non-empty हो
back()Last, vector non-empty हो
data()Contiguous range pointer
if(!marks.empty()) std::cout<<marks.front();
try{ std::cout<<marks.at(user_index); }
catch(const std::out_of_range&){
 std::cerr<<"Invalid index\n";
}

Last valid index non-empty vector में size()-1 है। Unsigned reverse loop में underflow से बचें।

Essential Vector Methods

MethodEffect
push_backEnd पर value
emplace_backEnd पर construct
pop_backLast remove; empty नहीं
insertPosition से पहले insert
eraseElement/range remove
clearAll elements destroy, capacity रह सकती है
swapContents/capacity exchange
marks.push_back(96);
marks.emplace_back(88);
marks.insert(marks.begin()+1,80);
marks.erase(marks.begin()+2);
auto removed=std::erase_if(marks,
 [](int m){return m<40;}); // C++20

pop_back value return नहीं करता। Already-created object में move और emplace के बीच automatic speed assumption न करें।

Size, Capacity, reserve और resize

std::vector<int> values;
values.reserve(100); // size 0
values.push_back(7); // size 1
values.resize(4);    // 7 0 0 0
  • size(): live elements।
  • capacity(): reallocation से पहले storage limit।
  • reserve(n): capacity request, size unchanged।
  • resize(n): element count change।
  • shrink_to_fit(): non-binding request।
reserve(100) के बाद values[50] invalid है क्योंकि capacity size नहीं है।

Known final size पर एक बार reserve उपयोगी है; हर push से पहले reserve growth strategy खराब कर सकता है। Doubling guaranteed नहीं है।

Iteration और Invalidation

for(int mark:marks) std::cout<<mark<<' ';
for(const Student& s:students) std::cout<<s.name;
std::sort(marks.begin(),marks.end());
  • Reallocation सभी iterators/pointers/references invalid करती है।
  • No reallocation में insert point से आगे handles invalid।
  • Erase position और उसके बाद handles invalid।
  • reserve केवल reallocation होने पर invalidates।
auto it=marks.begin();
marks.push_back(99); // it invalid हो सकता है
it=marks.begin();

iterators और algorithms आगे पढ़ें।

Complete Practical Program और Output

std::vector<int> marks;
marks.reserve(6);
for(int m:{72,88,65,91,88}) marks.push_back(m);
int total=std::accumulate(marks.begin(),marks.end(),0);
int highest=*std::max_element(marks.begin(),marks.end());
std::sort(marks.begin(),marks.end());
Sorted: 65 72 88 88 91 Average: 80.8 Highest: 91

Reserve ने elements नहीं बनाए, केवल insertion के लिए capacity दी। Total 404 है और floating-point division से average 80.8 आया।

Mistakes, Practice और Review

MistakeCorrection
Index == sizeOut of range
reserve के बाद indexpush/resize करें
Empty front/back/popempty check
Growth के बाद iteratorReacquire
clear frees capacityCapacity रह सकती है
Raw owning pointersValues/smart owners

Practice: duplicates remove करें; Student records mark के अनुसार sort करें; reserve से पहले/बाद size-capacity दिखाएं; negative values erase करें; at और [] compare करें।

  1. Header included?
  2. Index valid?
  3. Empty case?
  4. Size/capacity clear?
  5. Invalidation checked?
  6. Algorithm preconditions valid?

Authoritative संदर्भ

Complexity, reserve/resize और invalidation current working draft से verified हैं। Complete STL guide भी पढ़ें।

← 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.