C++ vector Basics | Initialization, Operations, Capacity, and Patterns
이 글의 핵심
vector initialization, operations, size vs capacity, reserve/resize, common UB and performance tips for real C++ code.
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 changesize()—don’tvec[0]until elements exist (push_back,resize, etc.).eraseinvalidates iterators—useerasereturn value or erase-remove idiom.- Mass
push_backwithoutreserve→ many reallocations. - Range-for while mutating size of the same vector → UB.
data()invalidated after reallocation—don’t hold raw pointers acrosspush_backif capacity might grow.
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 → checkempty()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<T>&orstd::vector<T>&&.
2. Initialization
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<int>(5) is size 5; vector<int>{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 elementscapacity(): allocated slot countreserve(n): capacity ≥ n, size unchangedresize(n): changes sizeshrink_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 iteratorreservemistaken forresizevector<bool>proxy quirks—considervector<uint8_t>for bitwise buffers- Signed/unsigned loop with
size()
7. Performance
reservewhen you know approximate final sizeemplace_backfor non-trivial typesconst auto&in range-for- erase-remove instead of repeated
erasein a loop
8. Best practices
- Read-only parameters:
const vector<T>& - 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
reservebeforeinsert/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
Related posts
- STL algorithms
- Range-based for