liveBook · Manning

Off-by-one error

As explained in 100 C++ Mistakes and How to Avoid Them

An off-by-one error is a boundary error in which an iteration or index range includes one element too many or too few.

An off-by-one error includes one element too many or too few in an iteration or index range. In a container loop, changing < to <= feels intuitive but tests one position beyond the last element. section 2.6

Reduce the opportunity for boundary mistakes by:

  • Replacing index-based iteration with a range-based for loop when the task processes each element. section 2.6
  • Using const references for class elements unless the loop must modify them; numeric values can usually be copied. section 2.6
Listing 2.11 Using index values to iterate over a container
template <typename T>
T sum(const std::vector<T>& values) {
    T sum = (T)0;
    for (int i = 0; i < values.size(); ++i)                 #1
        sum += values[i];
    return sum;
}
 
int main() {
    std::vector<int> values;
    for (int i = 0; i < 10; ++i)
        values.push_back(10*i + i);                         #2
    std::cout << sum(values) << '\n';
    return 0;
}

The indexed sum loop makes the continuation test, index access, and boundary risk explicit. section 2.6

Listing 2.12 Using range-based for values when iterating over a container
template <typename T>
T sum(const std::vector<T>& values) {
    T sum {};                                             #1
    for (const T& value : values)                         #2
        sum += value;
    return sum;
}
 
int main() {
    std::vector<int> values;
    for (int i = 0; i < 10; ++i)                          #3
        values.push_back(10*i + i);
    std::cout << sum(values) << '\n';
    return 0;
}

The range-based correction removes explicit continuation and update expressions while visiting every container element. section 2.6

How 100 C++ Mistakes and How to Avoid Them covers it

How deep it goes
Defines the boundary error, shows its misleading continuation test, and explains the safer range-based alternative.
Examples
Uses indexed and range-based vector summation examples, including the problematic <= continuation test.
What it assumes
Assumes basic C++ loops and containers while teaching range-based iteration from the indexed-loop comparison.
What you can do after
Apply it via range-based for loops to iterate over containers without manually writing boundary tests.
How it connects
Connects off-by-one errors with index-based loops, range-based for loops, containers, and references.

Also explained in

Compare how 4 books explain off-by-one error →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 C++ Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.