DEV Community

Yilong Wu
Yilong Wu

Posted on

Stop Using Arrays for Everything

I'm AlanWu. When I started C++, my answer to "I need to store multiple things" was always an array. int arr[1000]. Every time.

Then I discovered the STL containers and realized I'd been working way too hard. Here's when to use what.


vector — your new default

If you used to write int arr[1000], use vector<int> arr instead. It grows, it shrinks, it knows its own size, and you can pass it to functions without also passing the length separately.

// Old way
int scores[100];
int n = 0;
scores[n++] = 95;  // hope n doesn't exceed 99

// New way
vector<int> scores;
scores.push_back(95);  // never overflow, never count manually
Enter fullscreen mode Exit fullscreen mode

Use vector when: you need a list of things, in order, and you mainly add to the end or access by index.

Don't use vector when: you need to frequently insert or delete from the middle. That's O(n) — every element after shifts.


map — when you need to look stuff up by name

Arrays and vectors use integer indices. What if you want to look up a student's score by their name, not by number?

map<string, int> scores;
scores["Alice"] = 95;
scores["Bob"] = 88;

cout << scores["Alice"];  // 95
Enter fullscreen mode Exit fullscreen mode

Under the hood, map is a balanced binary search tree. Lookup is O(log n), not O(1). But for most things, it's fast enough and the code is dead simple.

Use map when: you have key-value pairs and keys are not just 0, 1, 2, 3...

Don't use map when: you only need integer indices — that's what vector is for. Or when you need O(1) average lookup — then use unordered_map.


unordered_map — same thing, but faster (usually)

unordered_map<string, int> scores;
scores["Alice"] = 95;
Enter fullscreen mode Exit fullscreen mode

Looks identical to map. The difference: unordered_map uses a hash table. Average lookup is O(1) instead of O(log n). But worst case is O(n) if there are collisions, keys have no order, and it uses more memory.

My rule: start with unordered_map. If you need keys in sorted order, switch to map.


set — when you only care if something exists

Need to track which IDs you've seen? Don't use a vector and loop through it every time.

set<int> seen;
seen.insert(42);
seen.insert(17);

if (seen.count(42)) {  // true — O(log n)
    // already seen it
}
Enter fullscreen mode Exit fullscreen mode

set stores unique values in sorted order. No duplicates allowed.

For O(1) average and no ordering needed: unordered_set.


The actual decision tree

  • Do you access by position (0, 1, 2...)? → vector.
  • Do you need to look up by something that isn't a number? → unordered_map.
  • Do those keys need to be sorted? → map.
  • Do you only care "have I seen this before"? → unordered_set.
  • Do you need those values in order or without duplicates? → set.

That covers 90% of cases.


The one you probably don't need: deque

I see beginners use deque because it sounds cool. Double-ended queue. Insert at both ends.

Unless you're writing a sliding window algorithm or a scheduler, you don't need deque. vector with push_back is faster and simpler.


Bottom line

Next time you reach for a plain array, ask: could a vector, map, or set do this in half the code? The answer is usually yes.

My GitHub: https://github.com/Cn-Alanwu

Top comments (0)