Pointers in memory Ready
main.c

                

Ready

Statements run 0 Lines printed 0
Ready

Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode

How it works

The ideas behind the lab

Exactly what you watched happen, in plain steps.

Address, pointer, dereference

Memory is a long row of numbered bytes; the number of a byte is its address. Every variable occupies some bytes, and &x gives the address of the first one. A pointer is a variable whose value is such an address — int *p means "p holds the address of an int". Writing *p (dereferencing) follows the address: *p is the int stored there, and you can read it or assign to it.

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

printf("%d", *p);  // 7 — read x through p
*p = 20;          // x is now 20

int *q = NULL;    // points nowhere (test with q != NULL)
int *w;           // wild: holds garbage — never use it
int x = 7; int *p = &x; (x is at 0x7ffe1000, p at 0x7ffe1008)
Expression Type Value Meaning
x int 7 The variable
&x int * 0x7ffe1000 The address of x
p int * 0x7ffe1000 The pointer's value: an address
*p int 7 The int at that address (x itself)
&p int ** 0x7ffe1008 Where the pointer itself is stored
sizeof p size_t 8 Every pointer is 8 bytes on 64-bit systems

The two operators

  1. & (address-of) gives where a variable is stored: &x.
  2. * (dereference) follows an address to the value: *p.
  3. In a declaration, * means "pointer": int *p; — in an expression it means "follow".
  4. *&x is x again: & and * undo each other.
  5. Print an address with %p: printf("%p", (void *) p);

Declaring and using pointers

  1. The type says what it points to: int *, double *, char *.
  2. int *p, *q; — every pointer name needs its own *.
  3. p = &x; makes p point to x; *p = 5; changes x.
  4. p = q; copies the address (both point to the same thing).
  5. *p = *q; copies the value (the pointers do not move).

NULL and wild pointers

  1. An uninitialised pointer is wild: it holds a random address.
  2. Dereferencing a wild pointer can change any memory or crash.
  3. NULL means "points nowhere" — give unused pointers this value.
  4. Always check if (p != NULL) before *p when p might be NULL.
  5. Dereferencing NULL crashes the program (segmentation fault).
Walkthrough

Addresses and values side by side

Every line, explained.

1 #include <stdio.h>
2
3 int main(void)
4 {
5 int age = 20;
6 int *p = &age; p holds the address of age.
7 printf("age = %d\n", age); Prints age = 20
8 printf("&age = %p\n", (void *) &age); An address, e.g. 0x7ffe5c1c (different on every run).
9 printf("p = %p\n", (void *) p); The same address.
10 printf("*p = %d\n", *p); Prints *p = 20
11 *p = *p + 1; age becomes 21 — through the pointer.
12 printf("age = %d\n", age); Prints age = 21
13 double d = 2.5;
14 double *dp = &d; A pointer to double.
15 printf("%zu %zu\n", sizeof dp, sizeof *dp); Prints 8 8 — the pointer and the double it points to.
16 int *none = NULL;
17 if (none != NULL) false, so the next line is skipped.
18 printf("%d\n", *none);
19 return 0;
20 }
Common mistakes

Spot the bug

Mistakes almost every beginner makes — and how to fix them.

Using an uninitialised pointer

✗ Wrong
int *p;
*p = 5;   // writes to a random address
✓ Right
int x;
int *p = &x;
*p = 5;

A pointer must point to real memory before you dereference it.

Forgetting the * for the second pointer

✗ Wrong
int *p, q;   // q is an int!
✓ Right
int *p, *q;

The * belongs to each name, not to the type.

Assigning a value instead of an address

✗ Wrong
int x = 5;
int *p = x;    // p = address 5?!
✓ Right
int x = 5;
int *p = &x;

A pointer needs an address. The compiler warns: "makes pointer from integer without a cast".

p = q when you meant *p = *q

✗ Wrong
p = q;     // now both point to the same int
✓ Right
*p = *q;   // copy the value

Without * you change where p points, not the int it points to.

Dereferencing NULL

✗ Wrong
int *p = NULL;
printf("%d", *p);   // crash
✓ Right
if (p != NULL)
    printf("%d", *p);

There is nothing at address 0. Check before following a pointer that may be NULL.

Practice

Check your understanding

Answer each question — you will see the explanation straight away.

0 / 5 correct
Question 1

int x = 4; int *p = &x; — what is *p?

Question 2

int x = 4; int *p = &x; *p = 10; — what is x now?

Question 3

Which operator gives the address of a variable?

Question 4

How big is a char * on a 64-bit system?

Question 5

Why initialise unused pointers to NULL?

Assessment

Pointer Basics quiz

Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.