Skip to content

Intermediate · Pointers · topic 21 of 60 · 30 min

Addresses and pointers

Explanation

Memory is a long row of numbered bytes, and every variable lives at some address. The & operator gives a variable's address; a pointer is a variable that stores an address. If int *p = &x;, then *p (dereferencing) reads or writes x itself. On 64-bit systems a pointer is 8 bytes. Print addresses with %p and a (void *) cast.

Memory as numbered boxes

Think of memory as a very long row of boxes, each holding one byte, and each with a number called its address. When you declare int x = 42;, the compiler reserves 4 consecutive boxes (on typical systems) and remembers where. The address of x is the number of its first byte.

output
int x = 42;

address    name   value
0x7ffc10   x      42        (4 bytes: 0x7ffc10 … 0x7ffc13)
Real addresses are long hexadecimal numbers like 0x7ffd5e8c3a1c; we use short ones in diagrams.

The & operator: "address of"

c
int x = 42;
printf("value %d, address %p\n", x, (void *) &x);   /* address changes from run to run */

Pointer variables

A pointer is a variable whose value is an address. Its type says what kind of value lives at that address: int * is "pointer to int", char * is "pointer to char". The * in a declaration means "this is a pointer".

output
int x = 42;
int *p = &x;          /* p holds the address of x */

address    name   value
0x7ffc10   x      42
0x7ffc18   p      0x7ffc10   ← p "points to" x

x          → 42
&x         → 0x7ffc10
p          → 0x7ffc10   (the same address)
*p         → 42         (the value AT that address)
&p         → 0x7ffc18   (p itself also lives somewhere)

Dereferencing: * as an operator

In an expression, *p means "the thing p points to". Reading *p reads x; assigning to *p changes x. This is how one piece of code can change a variable that belongs to someone else.

c
int x = 42;
int *p = &x;
*p = 50;                 /* writes through the pointer */
printf("%d\n", x);       /* 50: x itself changed */
(*p)++;                  /* brackets needed: *p++ would move p instead (precedence!) */
printf("%d\n", x);       /* 51 */
Careful: The * symbol means two different things. In a DECLARATION (int *p) it says "p is a pointer". In an EXPRESSION (*p = 5) it means "go to the address in p". Also note that in int *p, q; only p is a pointer; q is a plain int. Declare one pointer per line to avoid this trap.

Pointer sizes and types

c
printf("%zu %zu %zu\n", sizeof(int *), sizeof(char *), sizeof(double *));   /* 8 8 8 on 64-bit systems */
Every data pointer has the same size on a given platform; the type tells the compiler how to read what is pointed at.

A pointer must point to the right type. int *p = &d; where d is a double is a compile warning and a bug: *p would read the first 4 bytes of the double as if they were an int. void * is a generic pointer that can hold any data address but cannot be dereferenced until converted to a real type.

Think of it like this: A variable is a house; its address is the house number; a pointer is a slip of paper with that house number written on it. Reading the slip (p) gives you the number. Going to that house and opening the door (*p) gives you what is inside. Two slips can carry the same address, and both lead to the same house.
Tip: When pointer code confuses you, draw boxes: one box per variable with its name, address and value, and arrows from pointers to what they point at. Professionals do this too.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Addresses and pointers · 1/7

Pointers

In this module you will learn pointers, the most powerful idea in C.

Prefer a video by a teacher? Find free videos on “c pointers explained for beginners address dereference memory diagram” on YouTube ↗

In real life: Reading a hardware register

In embedded C, devices such as GPIO pins and timers appear at fixed memory addresses. Firmware reads a sensor's status by creating a pointer to that address and dereferencing it. (The address below is invented for illustration; real ones come from the chip's datasheet. Module 12 explains volatile.)

c
#include <stdint.h>

#define STATUS_REG ((volatile uint32_t *) 0x40001000u)   /* illustrative address only */

int sensor_ready(void) {
    return (*STATUS_REG & 0x1u) != 0;   /* read the register through the pointer */
}

Practice (0/3 done)

Task 1 · Question

What does this print? int a = 5; int *p = &a; *p = *p + 10; printf("%d\n", a);

Task 2 · Question

In int *p, q; what are p and q?

Task 3 · Code · Javascript

Simulate memory and pointers in JavaScript, which runs here. memory is an array (index = address). Write deref(memory, p) that returns memory[p], and store(memory, p, value) that writes value at address p and returns nothing. Then, using only these functions, write swapAt(memory, pa, pb) that swaps the values at two addresses (like a C swap with pointers).

Quick quiz

Question 1

1.What does &x give?

Question 2

2.If int *p = &x; what does *p give?

Question 3

3.On a typical 64-bit system, sizeof(char *) is…

Question 4

4.How should a pointer be printed with printf?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does &x give?

Answer: The address of x

& is the address-of operator.

If int *p = &x; what does *p give?

Answer: The value of x

Dereferencing reads the pointed-to value.

On a typical 64-bit system, sizeof(char *) is…

Answer: 8

All data pointers are 8 bytes on 64-bit systems.

How should a pointer be printed with printf?

Answer: %p with a (void *) cast

%p expects a void pointer.

Which printf format prints a ptrdiff_t?Related

Answer: %td

t is the length modifier for ptrdiff_t.

From Pointer arithmetic

For a struct pointer s, what is s->name the same as?Related

Answer: (*s).name

The arrow operator dereferences the pointer and then picks the member.

From Pointers, the stack and the heap

What is the zero value of a pointer?Related

Answer: nil

An unset pointer is nil.

From Pointers without fear

What is in an int variable declared inside main with int n; and no value?Related

Answer: Garbage: reading it is undefined behaviour

Local variables are not set to zero automatically. Always initialise them.

From Variables, types and constants

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 4 more topics in “Pointers” before its exam: Pointers and functions, Pointers and arrays, Pointer arithmetic, NULL, dangling pointers and pointers to pointers.
  2. Module 5 exam: Pointers · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Dynamic memory. 60 topics left in the course before the final exam.

← Previous: Buffer overflows and safe string handling