[2026] C++ vector Basics | Initialization, Operations, Capacity, and Patterns
이 글의 핵심
std::vector crash from vec[10] with size 3: at() vs [], reserve vs resize, erase-remove, iterator invalidation, emplace_back, and production buffer patterns.
Introduction: Segfault from vec[10]
“I indexed vec[10] and the program died”
std::vector is the standard dynamic array: contiguous storage, amortized O(1) push at the end, O(1) random access. Think of a bookshelf where slots stay in order and you read slot i in one step—same layout idea as a C array, but the shelf can grow. operator[] does not bounds-check—out-of-range access is undefined behavior (often SIGSEGV).
Analogy: vector is also an expandable drawer cabinet—opening drawer 10 when only three exist is invalid.
Bad:
std::vector<int> vec = {1, 2, 3};
int value = vec[10]; // UB — size is 3
Safer:
int value = vec.at(10); // throws std::out_of_range
// or
if (10 < vec.size()) { int value = vec[10]; }
Common pitfalls (short)
- reserve(100) does not change size()—don’t
vec[0]until elements exist (push_back,resize, etc.). - erase invalidates iterators—use
erasereturn value or erase-remove idiom. - Mass
push_backwithout reserve → many reallocations. - Range-for while mutating size of the same vector → UB.
- data() invalidated after reallocation—don’t hold raw pointers across push_back if capacity might grow. 아래 코드는 mermaid를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
flowchart TB
subgraph choice[Choosing a container]
A[Need dynamic array] --> B{Purpose}
B -->|index + push back| C[std::vector]
B -->|push/pop both ends| D[std::deque]
B -->|key lookup| E["map / unordered_map"]
B -->|sorted unique keys| F[std::set]
end
subgraph vector_opt[vector tips]
C --> G["reserve for known size"]
C --> H["emplace_back to avoid temps"]
end
Table of contents
- Problem scenarios
- Initialization
- Operations
- Capacity
- Examples
- Common errors
- Performance
- Best practices
- Production patterns
- Checklist
1. Problem scenarios
- Empty CSV row →
cells[0]→ crash → check empty() first. - Erase in loop → use it = vec.erase(it) or erase-remove.
- Loading millions of rows without reserve → slow → reserve(estimated).
- Pass by value huge vectors → expensive → const std::vector
& or std::vector&& .
2. Initialization
다음은 간단한 cpp 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
std::vector<int> v1; // empty
std::vector<int> v2(5); // five default-initialized ints
std::vector<int> v3(5, 42); // five 42s
std::vector<int> v4 = {1,2,3,4,5}; // initializer list
() vs {}: vector(5) is size 5; vector{5} is one element with value 5.
3. Operations
push_back/emplace_backinsert/erase(O(n) for middle)- pop_back, clear
- [], at(),
front/back, data()
4. Capacity
- size(): number of elements
- capacity(): allocated slot count
- reserve(n): capacity ≥ n, size unchanged
- resize(n): changes size
- shrink_to_fit(): non-binding request to shrink capacity
5. Examples
erase-remove
vec.erase(std::remove(vec.begin(), vec.end(), value), vec.end());
sort + unique
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
6. Common errors
- Out-of-range []
- erase + invalid iterator
- reserve mistaken for resize
- vector
proxy quirks—consider vector<uint8_t> for bitwise buffers - Signed/unsigned loop with size()
7. Performance
- reserve when you know approximate final size
- emplace_back for non-trivial types
- const auto& in range-for
- erase-remove instead of repeated erase in a loop
8. Best practices
- Read-only parameters: const vector
& - Return large vectors by value (move/RVO in C++11+)
- Don’t use data() across operations that reallocate
9. Production patterns
- Reuse buffer: clear() keeps capacity for the next batch
- Conditional
reservebefore insert/appendranges
10. Checklist
-
reservefor bulk inserts when size known -
emplace_backfor heavy types - Safe erase patterns
- Avoid
vector<bool>when you need pointers/refs to elements
FAQ
Is reserve too large bad?
A. It wastes memory but is safe; don’t reserve orders of magnitude more than you need.
emplace_back always?
A. Most valuable for non-trivial types; for int, similar to push_back.
vector vs array?
A. std::array<T,N>: fixed size at compile time; vector: runtime size. One-line summary: Know size vs capacity, use reserve, and never trust [] for bounds without proof. Next: vector/string performance
Keywords
C++, std::vector, STL, dynamic array, reserve, capacity, emplace_back, iterator