Arrays, std::array & std::vector
অ্যারে — পুরনো থেকে আধুনিক
1. C-style Arrays — The Old Way
#include <iostream>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; ++i) std::cout << arr[i] << " ";
std::cout << "\n";
std::cout << "size in bytes = " << sizeof(arr) << "\n";
}
arr[10] on a 5-element array is undefined behavior. C-arrays decay to pointers when passed to functions, losing size info. Avoid in modern code.
2. std::array — Compile-time Size
A safer wrapper around a fixed-size array. Knows its size, doesn't decay, supports STL operations.
#include <iostream>
#include <array>
int main() {
std::array<int, 5> a = {10, 20, 30, 40, 50};
for (int x : a) std::cout << x << " ";
std::cout << "\nsize = " << a.size() << "\n";
std::cout << "first = " << a.front() << "\n";
std::cout << "last = " << a.back() << "\n";
// std::cout << a.at(10); // throws std::out_of_range
}
3. std::vector — Dynamic Size
A growable array. Most-used C++ container. Default choice unless you have a reason otherwise.
#include <iostream>
#include <vector>
int main() {
std::vector<int> v; // empty
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.emplace_back(4); // constructs in-place
std::cout << "size = " << v.size()
<< ", capacity = " << v.capacity() << "\n";
for (int x : v) std::cout << x << " ";
std::cout << "\n";
}
4. When to Use Which
| Container | Size | Memory | Use when |
|---|---|---|---|
| C-array | Fixed, compile-time | Stack | Almost never (legacy) |
std::array<T,N> | Fixed, compile-time | Stack | Known size, want STL features |
std::vector<T> | Dynamic | Heap | Default. Size unknown or growing |
5. 2D Arrays
#include <iostream>
#include <vector>
int main() {
std::vector<std::vector<int>> mat(3, std::vector<int>(4, 0));
mat[1][2] = 42;
for (const auto& row : mat) {
for (int x : row) std::cout << x << " ";
std::cout << "\n";
}
}
6. Practice Problems
- Create a vector of 10 zeros.
✨ Show Answer
std::vector<int> v(10, 0); - Sum all elements in a vector.
✨ Show Answer
int s = 0; for (int x : v) s += x; - Find the max element.
✨ Show Answer
#include <algorithm> int m = *std::max_element(v.begin(), v.end()); - Difference between
v[i]andv.at(i)?✨ Show Answer
v[i]— no bounds check (faster, undefined behavior on out-of-range).v.at(i)— throwsstd::out_of_range. Useat()when index comes from external input. - Reverse a vector in place.
✨ Show Answer
std::reverse(v.begin(), v.end()); - Why does vector double its capacity on growth?
✨ Show Answer
To make
push_backamortized O(1). Doubling means the total work over N inserts is O(N), not O(N²) (which copying once per insert would give). - What's the size of
sizeof(arr)forint arr[5]?✨ Show Answer
20 bytes on a typical 32-bit-int system (5 × 4).
- Build a 5×5 multiplication table as a
std::vector<std::vector<int>>.✨ Show Answer
std::vector<std::vector<int>> t(5, std::vector<int>(5)); for (int i = 0; i < 5; ++i) for (int j = 0; j < 5; ++j) t[i][j] = (i+1) * (j+1); - Demo: vector decay vs std::array preserving size when passed.
✨ Show Answer
C-array:
void f(int a[])—ais a pointer, no size.std::array:void f(std::array<int,5>& a)— size is part of the type.std::vector:v.size()always available. - Difference between
push_backandemplace_back?✨ Show Answer
push_back(x)copies/movesxinto the container.emplace_back(args...)constructs the element in place using the args. Saves a move/copy for complex types. - Insert 99 at position 2 in a vector.
✨ Show Answer
v.insert(v.begin() + 2, 99); - Remove element at index 3.
✨ Show Answer
v.erase(v.begin() + 3); - Why prefer
std::vectoroverstd::listusually?✨ Show Answer
Vector is contiguous in memory → cache-friendly. List has scattered nodes with overhead per element. Vector wins almost always for traversal, even with insertions in the middle.
- Print elements of
std::array<int,3>{1,2,3}with range-for.✨ Show Answer
std::array<int, 3> a = {1,2,3}; for (int x : a) std::cout << x << " "; - Reserve capacity 1000 for a vector before pushing.
✨ Show Answer
v.reserve(1000); // avoids reallocation - Difference between
resizeandreserve?✨ Show Answer
resize(n)changes the actual size (creates default elements if growing).reserve(n)only changes capacity — size stays the same. - Does
std::vector<bool>behave like other vectors?✨ Show Answer
No! It's specialized to pack bits.
v[i]returns a proxy, notbool&. This breaks generic code. Preferstd::vector<char>orstd::deque<bool>when you need a real container of bools. - Clear all elements but keep the capacity.
✨ Show Answer
v.clear(); // size becomes 0, capacity unchanged
Summary
Modern C++ has three array types. Use std::vector by default; std::array
for fixed sizes; raw C-arrays only for legacy interop. Vectors grow by doubling for amortized O(1) append.
Use at() for bounds-checked access, [] for fast unchecked access.