Common C++ Mistakes
Learn from these common pitfalls to write better code
Array and Index Mistakes
Off-by-One Errors in Loops
Arrayfor (int i = 0; i <= n; i++) {
arr[i] = 0; // Buffer overflow!
}
for (int i = 0; i < n; i++) {
arr[i] = 0; // Safe access
}
Why This Happens
Arrays are 0-indexed. An array of size n has valid indices 0 to n-1. Using <= instead of < accesses index n, which is out of bounds.
Integer Overflow in Midpoint Calculation
Binary Searchint mid = (left + right) / 2;
// Overflow when left + right > INT_MAX
int mid = left + (right - left) / 2;
// Safe from overflow
Why This Happens
When left and right are both large (close to INT_MAX), their sum overflows. The correct formula avoids adding them directly.
Accessing Empty Container
STLvector v;
int x = v[0]; // Undefined behavior!
int y = v.back(); // Also undefined!
vector v;
if (!v.empty()) {
int x = v[0];
int y = v.back();
}
Why This Happens
Always check if a container is empty before accessing elements. This is especially important for stacks, queues, and vectors.
Pointer and Memory Mistakes
Dereferencing NULL Pointer
PointerTreeNode* root = nullptr;
int val = root->val; // Crash!
TreeNode* root = nullptr;
if (root != nullptr) {
int val = root->val;
}
Why This Happens
In tree/linked list problems, always check for null before accessing members. This is the most common cause of runtime errors.
Forgetting to Move Pointer in Linked List
Linked Listwhile (curr != nullptr) {
curr->val *= 2;
// Forgot curr = curr->next;
// Infinite loop!
}
while (curr != nullptr) {
curr->val *= 2;
curr = curr->next;
}
Memory Leak - Forgetting to Delete
Memoryint* arr = new int[100];
// ... use arr ...
// Memory leak - forgot delete[] arr;
// Use vector instead
vector arr(100);
// Or use smart pointers
unique_ptr arr(new int[100]);
Best Practice
In competitive programming, use STL containers. In production, prefer smart pointers (unique_ptr, shared_ptr) over raw pointers.
STL Mistakes
Modifying Container While Iterating
Iteratorfor (auto it = v.begin(); it != v.end(); it++) {
if (*it == target) {
v.erase(it); // Iterator invalidated!
}
}
// Method 1: erase returns new iterator
for (auto it = v.begin(); it != v.end(); ) {
if (*it == target) it = v.erase(it);
else ++it;
}
// Method 2: Use erase-remove idiom
v.erase(remove(v.begin(), v.end(), target), v.end());
Using Wrong Comparator for Priority Queue
Heap// Default is MAX heap
priority_queue pq;
// For MIN heap, need this:
priority_queue, greater> minPq;
// For custom types:
struct Compare {
bool operator()(const pair& a,
const pair& b) {
return a.first > b.first; // Min heap
}
};
priority_queue, vector>, Compare> pq;
Key Point
The comparator logic is opposite of what you might expect. Use greater<int> for min-heap, less<int> (default) for max-heap.
Passing Large Containers by Value
Performancevoid process(vector nums) { // Copies entire vector!
// ...
}
void process(const vector& nums) { // Reference
// ...
}
void modify(vector& nums) { // Non-const if modifying
// ...
}
Logic Mistakes
Assignment Instead of Comparison
Operatorif (x = 5) { // Always true! Assigns 5 to x
// ...
}
if (x == 5) { // Compares x with 5
// ...
}
Integer Division Truncation
Mathint a = 5, b = 2;
double result = a / b; // result = 2.0, not 2.5!
int a = 5, b = 2;
double result = (double)a / b; // result = 2.5
// Or: double result = a * 1.0 / b;
Forgetting Base Case in Recursion
Recursionint factorial(int n) {
return n * factorial(n - 1); // Stack overflow!
}
int factorial(int n) {
if (n <= 1) return 1; // Base case!
return n * factorial(n - 1);
}
Performance Mistakes
Using size() in Loop Condition
Performancefor (int i = 0; i < v.size() - 1; i++) {
// If v is empty, v.size()-1 underflows!
}
int n = v.size();
for (int i = 0; i + 1 < n; i++) {
// Safe from underflow
}
Why This Happens
size() returns size_t (unsigned). If size is 0, subtracting 1 underflows to a huge positive number!
String Concatenation in Loop
Stringstring result = "";
for (char c : chars) {
result = result + c; // Creates new string each time!
}
string result;
result.reserve(chars.size());
for (char c : chars) {
result += c; // Appends in place
}