Skip to main content

Pointer Arithmetic & One-Past-the-End

intermediate15 min readLesson 89 of 148

What p + 1 really means, why one-past-the-end is legal but one-past-that is not, and the subtraction idiom.

Scaling by the pointee

p + 1 does not add one byte โ€” it advances by sizeof *p bytes. For an int * on this platform that is 4 bytes; for a struct Big *, maybe 64. The compiler does the scaling; you do the reasoning:

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;          /* points at arr[0] */
p + 3                  /* points at arr[3] */
*(p + 3)               /* 40 โ€” the value there */
p[3]                   /* exactly the same thing: a[i] is *(a + i) */

The array-index operator is defined in terms of pointer arithmetic. That is why 3[arr] also compiles (it is *(3 + arr)) โ€” legal, unforgettable once seen, and never written on purpose.

The one legal out-of-bounds pointer

C guarantees you may form a pointer one past the end of an array object. You may compare with it and subtract from it, but you may not dereference it:

int *end = arr + 5;    /* legal: one past the last element */
for (int *p = arr; p != end; p++) use(*p);   /* the classic walk */
*(arr + 5)             /* UB: dereferencing the one-past pointer */
arr + 6                /* UB: even forming it */

This is not pedantry: <stdlib.h>'s own conventions rely on it. Functions returning "position" return NULL or an end pointer, and algorithms like qsort reason in [first, last) half-open ranges โ€” exactly this shape.

Subtraction gives counts

size_t n = (size_t)(end - start);   /* number of elements, not bytes */

Subtracting two pointers into the same array yields ptrdiff_t: how many elements apart. Subtracting pointers into different objects is undefined.

Walking with pointers instead of indices

/* sum an array the pointer way โ€” same machine result, different mental model */
int total = 0;
for (const int *p = arr, *end = arr + 5; p != end; ++p) total += *p;

Neither style is "faster" by definition. The pointer style generalizes to structures where indices make no sense (linked lists, Module 9); the index style resists off-by-one errors better in dense arrays. Choose per situation.

Check your understanding

  • sizeof an array of 7 double is 56; arr + 3 advances how many bytes? (24.)
  • Is arr + 5 legal for a 5-element array? (Yes โ€” one-past-the-end. Dereferencing it is not.)
  • What is *(arr + 2) == arr[2]? (True by definition of [].)

Now practice

Address Walking GymPointer arithmetic under exam conditions: one-past-the-end, subtraction, walking.4 challenges ยท ยท ~24 min