testing-debugging · beginner · ~15 min

Fix Off-By-One Linear Search

Debug and prevent reverse-loop off-by-one errors and unsigned index underflows.

Challenge

Off-by-one errors in reverse loops frequently lead to out-of-bounds array reads and skipped initial elements. When iterating backwards with size_t, decrementing past zero wraps around to SIZE_MAX.

Your Task

Implement:

int find_last_occurrence(const int *arr, size_t len, int target);

Find the zero-based index of the last occurrence of target in array arr of size len.

Rules

  1. If arr == NULL or len == 0, return -1.
  2. Scan from the end of the array to find the last occurrence.
  3. Return the zero-based index as an int.
  4. If target does not appear in arr, return -1.

Example

int a[] = {10, 20, 30, 20, 40};
find_last_occurrence(a, 5, 20); // returns 3 (not 1)

Input format

arr: pointer to integer array; len: size_t element count; target: integer search value.

Output format

Returns zero-based index of last match, or -1 if not found or invalid.

Constraints

Zero dynamic allocations. Safe loop termination with unsigned size_t.

Starter code

#include <stddef.h>

/* Find zero-based index of last occurrence of target in arr. Return -1 if not found or arr is NULL. */
int find_last_occurrence(const int *arr, size_t len, int target) {
    (void)arr; (void)len; (void)target;
    return -1;
}

Common mistakes

Writing i >= 0 with size_t resulting in an infinite loop; indexing arr[i] when i starts at len (out of bounds).

Edge cases to handle

len == 0 returns -1; single-element match returns 0; target at index 0 found correctly; duplicate elements return last index.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.