Chapter 8

Home

Debugging Your First Errors

Every programmer writes bugs. The skill isn't avoiding them — it's finding them quickly. This chapter covers the most common beginner mistakes and how to spot them.

Off-by-One Errors

The most common bug in CP. Arrays start at index 0, so the last index is n-1, not n.

Buggy

// C++ — accessing arr[n] when last index is n-1
for (int i = 0; i <= n; i++) {
    cout << arr[i] << "\n";  // crash when i == n
}

Fixed

// Use < not <=
for (int i = 0; i < n; i++) {
    cout << arr[i] << "\n";
}

Print Debugging

When the answer is wrong, print intermediate values. This is the simplest and most effective debugging technique.

int total = 0;
for (int i = 0; i < n; i++) {
    total += arr[i];
    // Temporary debug print
    cerr << "i=" << i << " val=" << arr[i]
         << " total=" << total << "\n";
}
cout << total << "\n";

Use cerr in C++ for debug output — it goes to stderr and the judge ignores it. In Rust, use eprintln!().

💡 Remove debug prints before submitting

Extra output to stdout will cause a wrong answer. Use cerr / eprintln! so you can leave them in during development without affecting the judge.

Common Pitfalls

Uninitialized variables

int total;  // BAD: could be anything
total += x; // garbage + x = garbage

int total = 0;  // GOOD
total += x;

Integer overflow

// C++: int holds up to ~2.1 billion
int x = 1000000, y = 1000000;
cout << x * y;  // overflow!

// Use long long instead
long long x = 1000000, y = 1000000;
cout << x * y;  // 1e12 ✓

In Rust, use i64 instead of i32 for safety.

Division by zero

int x = 5, y = 0;
cout << x / y;  // crash!

// Guard before dividing
if (y != 0) {
    cout << x / y;
}

Reading Compiler Errors

The compiler is your first debugger. It tells you exactly where the problem is — read the line number and message.

compile error read the line number & error message fix and retry

Key Takeaways

Practice