Moving Pointers Safely- Embedded C Programming Course

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

Free C Programming Course · Pointers · Lecture 9

Moving Pointers Safely

Understand the difference between *(p + n) and p += n, subtract pointers with ptrdiff_t, and keep every pointer on valid memory in embedded C programming.

What You Will Learn

This free C programming course lecture finishes the pointer arithmetic topic. In this free C tutorial you will learn when an expression reads a neighbouring element without moving the pointer, when a statement really moves it, how to count elements between two pointers, and the rules that keep a pointer on valid memory. These habits are essential for safe embedded C programming.

  • Expression versus assignment: *(p + 2) against p += 2
  • Pointer subtraction and the ptrdiff_t type
  • The “one past the end” rule
  • Walking an array with a begin and end pointer
  • Why moving a pointer onto invalid memory is dangerous

Prerequisites

Complete the previous lecture on pointer arithmetic scaling in this free embedded C course. You should also know how arrays are stored in consecutive memory.

Reading Ahead Without Moving

A frequent point of confusion is the difference between computing an address and storing it. Look at these two lines for an int pointer p that points at the start of an array:

int v = *(p + 2);   /* read element 2, p is unchanged */
p += 2;             /* move p itself two elements ahead */

The expression p + 2 creates a temporary address two elements ahead. The star then reads from it. Nothing is assigned back to p, so p still points at element 0. In contrast, p += 2 is an assignment, so p now holds the new address and every later use of *p sees element 2.

Expression *(p + 2) compared with statement p += 2

index012345
value51015202530
p, beforep–––––
*(p + 2) reads––read–––
p after *(p + 2)p–––––
p after p += 2––p–––

Suggested image 4: two strips of array cells, one showing a read at offset two and one showing the pointer moved. ALT text: “free embedded C course pointer moves versus pointer expression”.

Subtracting Two Pointers

When two pointers of the same type point into the same array, their difference tells you how many elements lie between them. The result type is ptrdiff_t, declared in stddef.h, a signed integer wide enough for any pointer difference. Print it with the %td format. Like all pointer arithmetic, the result counts elements, not bytes.

Program: Walk an Array with Pointers

Save this as ptr_walk.c. It reads ahead, moves the pointer, subtracts pointers, and finally sums the array with a begin and end pointer.

#include <stdio.h>
#include <stddef.h>

int main(void)
{
    int a[6] = {5, 10, 15, 20, 25, 30};
    int *p = a;

    printf("*(p+2) = %d, p still at index %td\n", *(p + 2), p - a);

    p += 2;
    printf("after p += 2 : index %td, *p = %d\n", p - a, *p);

    int *q = &a[5];
    ptrdiff_t gap = q - p;
    printf("q - p = %td elements (%td bytes)\n", gap, (char *)q - (char *)p);

    int *end = a + 6;      /* one past the last element: legal to form */
    int sum = 0;
    for (int *it = a; it != end; it++)
        sum += *it;
    printf("sum via pointer walk = %d\n", sum);
    return 0;
}
$ gcc -Wall -Wextra -std=c11 -o ptr_walk ptr_walk.c
$ ./ptr_walk
*(p+2) = 15, p still at index 0
after p += 2 : index 2, *p = 15
q - p = 3 elements (12 bytes)
sum via pointer walk = 105

The first line proves that reading *(p + 2) left p at index 0. The second shows that p += 2 did move it. The subtraction q – p gives 3 elements, which equals 12 bytes for 4-byte ints, confirming that the language counts in elements. The final loop adds 5 + 10 + 15 + 20 + 25 + 30 = 105.

Keeping Pointers on Valid Memory

When you move a pointer, nothing guarantees that it still refers to a variable of the right type, or to any valid object at all. The compiler decides where variables live, and you do not control the order. The only layout you can rely on is that array elements sit one after another. That is why pointer arithmetic is meant for arrays.

Pointer positionAllowed to form?Allowed to dereference?
Any element inside the arrayYesYes
One position past the last elementYesNo
Before the first elementNo, undefined behaviourNo
Two or more past the endNo, undefined behaviourNo
Next to an unrelated variableNo, layout is not guaranteedNo
Undefined behaviour is silent. Stepping outside an array often appears to work on your PC and then corrupts a neighbouring variable on the target board. Treat the valid range as a hard boundary.

Pointer Walk Versus Array Index

You can write the same loop in two styles. The index style uses a counter and the subscript operator. The pointer style uses a begin and an end pointer. Both compile to similar machine code on modern compilers, so choose the one that makes your intent clearer.

StyleLoop headerStrength
Indexfor (size_t i = 0; i < n; i++)Easy to read, gives you the position
Pointerfor (int *it = a; it != end; it++)No counter, natural for ranges and buffers

When you need the position inside a pointer loop, subtract the base: it - a gives the index. When you only need the values, the pointer style removes one variable. In firmware that processes a stream of samples, this is a common and tidy pattern.

Real-World Use: Ring Buffer Pointers

A UART receive ring buffer keeps a head and a tail pointer inside a fixed array. After each byte the pointer is incremented, and when it reaches the end it wraps back to the start. The one-past-the-end rule is what makes the comparison head == buffer + SIZE legal. Subtracting the pointers gives how many bytes are waiting, handled with care around the wrap point.

Troubleshooting Checklist

  • Garbage values when reading: check the pointer did not move past the end.
  • Off-by-one results: remember that end points past the last element, so the loop test uses != or <.
  • Wrong byte distance: pointer subtraction gives elements, cast to char * if you need bytes.
  • Compiler warnings about incompatible pointer types: you are subtracting different types, fix the declarations.

Best Practices

  • Keep the original base pointer, and move a copy when you need to walk.
  • Prefer the begin/end pointer pair for loops.
  • Validate lengths received from outside before you step through a buffer.
  • Use a bounds check in security-sensitive code instead of trusting incoming sizes.

Key Takeaways

  • *(p + n) reads element n and leaves p alone, p += n moves p.
  • Subtracting same-type pointers gives an element count of type ptrdiff_t.
  • A pointer may point inside an array or exactly one past its end, never further.
  • Pointer arithmetic is only meaningful across elements of one array.

Conclusion

You can now tell apart reading ahead and moving, measure the distance between pointers and keep your pointers inside safe bounds. These skills turn pointers from a source of crashes into a precise tool for embedded firmware. The final lecture of this block gathers everything from dereferencing to pointer arithmetic into a quiz and a set of interview questions for your free C programming course practice.

Frequently Asked Questions

Is *(p + 2) the same as p[2]?

Yes. The subscript operator is defined as exactly that expression.

What type does pointer subtraction return?

ptrdiff_t, a signed integer type from stddef.h.

Can a pointer point one past the end of an array?

Yes, you may form and compare it, but you must not dereference it.

What happens if I move a pointer before the array start?

The behaviour is undefined, even if you never dereference it.

Why use a begin and end pointer loop?

It needs no index variable and states the range clearly.

Do these rules matter on microcontrollers?

More than on a PC, since bad pointers can overwrite registers or other variables without any error message.

Test What You Learned

Modify the walk program to find the largest value using only pointers, then take the quiz in the next lecture of this free embedded C course.

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *