Ch5.3: Dereferencing

Overview

A pointer stores an address. Dereferencing means: use the pointer to access the object at that address.

In this chapter, you will learn:

1. What does dereferencing mean?

If a pointer stores an address, dereferencing means “go to that address and access the object stored there”.


value:
Address:   3000
Memory:   [ 42 ]

p:
Address:   4000
Memory:   [ 3000 ]   ← p stores address of value

#include <memory>

int value{42};
int *p = ::std::addressof(value);

int x = *p;   // x becomes 42

2. Reading through a pointer

Dereferencing lets you read the value stored at the pointer’s address.


int n{100};
int *p = ::std::addressof(n);

int copy = *p;   // copy becomes 100

3. Writing through a pointer

Dereferencing also lets you modify the object the pointer refers to.


int n{5};
int *p = ::std::addressof(n);

*p = 20;   // changes n to 20

4. Dereferencing pointer-to-pointer

If you have a pointer-to-pointer, you can dereference it twice.


int value{7};
int *p = ::std::addressof(value);
int **pp = ::std::addressof(p);

int x = **pp;   // x becomes 7

value:
Address:   3000
Memory:   [ 7 ]

p:
Address:   4000
Memory:   [ 3000 ]

pp:
Address:   5000
Memory:   [ 4000 ]

**pp → *p → value → 7

5. Dereferencing nullptr is undefined behavior

A pointer must point to a valid object before you dereference it. Dereferencing nullptr is undefined behavior.


int *p = nullptr;

// *p = 10;   // undefined behavior — never do this

6. Dereferencing invalid pointers is a serious memory‑safety vulnerability

Dereferencing an invalid pointer is not just a bug — it is a serious memory‑safety vulnerability. It can lead to:

A pointer is invalid if it is:

Examples


// 1. Null pointer
int *p = nullptr;
// *p = 10;   // undefined behavior

// 2. Uninitialized pointer
int *q;
// *q = 10;   // undefined behavior

// 3. Dangling pointer
int *r = nullptr;
{
    int x{5};
    r = ::std::addressof(x);
} // x is destroyed here
// *r = 10;   // undefined behavior

// 4. Forged pointer
int *s = reinterpret_cast(12345);
// *s = 10;   // undefined behavior

Rule: Only dereference a pointer if you are absolutely certain it points to a valid, alive object.

7. Use sanitizers to detect invalid dereferences

Modern compilers provide tools that detect invalid pointer dereferences at runtime. You should always enable them during development.

AddressSanitizer


-fsanitize=address

Detects:

Memory Tagging (WebAssembly)


-fsanitize=memtag

Detects:

These tools make pointer bugs easier to find and fix.

8. Printing dereferenced values

You can print the value obtained by dereferencing just like any other value.


#include <fast_io.h>
#include <memory>

int n{55};
int *p = ::std::addressof(n);

println(*p);   // prints 55

Key takeaways