Ch5.2: Pointer Basics
Overview
A pointer is a variable that stores an address. It does not store
a value like 42; it stores the location of an object in memory.
In this chapter, we introduce only the syntax of pointers:
- how to declare pointers (including pointer-to-pointer)
- how to obtain an address using
::std::addressof - how to store that address in a pointer
- why pointers must always be initialized
- how to print pointers with
pointervw - how to visualize pointers with simple pseudo‑graphs
We use only simple types such as ::std::size_t, int,
char, and double. Containers will be covered later in Ch5.12.
1. Include <memory> for ::std::addressof
To obtain the address of an object, we use ::std::addressof.
It is defined in the <memory> header.
#include <memory> // for ::std::addressof
We use ::std::addressof instead of & because:
- it always returns the true address of the object
- it works even if a type overloads
operator& - it is the recommended modern C++ approach
2. What is a pointer?
Every object in memory has an address. A pointer is a variable that stores such an address.
Address: 2000 2001 2002 2003
Memory: [ 7 ][ 7 ][ 7 ][ 7 ]
↑
x lives here
#include <memory>
::std::size_t x{7};
::std::size_t *p = ::std::addressof(x); // p stores the address of x
3. Declaring pointers
A pointer type is written as T*, meaning “pointer to T”.
In this tutorial, we prefer writing the * next to the variable name:
int *ip;
char *cp;
::std::size_t *sp;
double *dp;
Always initialize pointers
You must always initialize a pointer. An uninitialized pointer contains an unpredictable address, and using it is undefined behavior.
int *p = nullptr; // safe: p points to nothing
char *q = nullptr; // safe
::std::size_t *r = nullptr; // safe
Later, when you have a real object, you can assign its address:
int value{42};
int *p = ::std::addressof(value);
A common beginner trap
This declaration is misleading:
int* p, q; // q is NOT a pointer
Only p is a pointer. q is a plain int.
Writing the * next to the variable name makes the meaning clearer:
int *p, q; // p is a pointer, q is an int
Even better, declare one pointer per line and always initialize it:
int *p = nullptr;
int *q = nullptr;
4. Pointer to pointer
A pointer can also store the address of another pointer. This is called a pointer-to-pointer.
int value{42};
int *p = ::std::addressof(value); // p points to value
int **pp = ::std::addressof(p); // pp points to p
value:
Address: 3000
Memory: [ 42 ]
p:
Address: 4000
Memory: [ 3000 ] ← p stores address of value
pp:
Address: 5000
Memory: [ 4000 ] ← pp stores address of p
You can keep adding more * levels, but pointer-to-pointer is the most common.
5. nullptr
A pointer can also store “no address”.
This is written as nullptr.
int *p = nullptr; // p does not point to anything
int **pp = nullptr; // pp also does not point to anything
We will explore nullptr more in Ch5.4.
6. Printing pointers
A pointer stores an address, and sometimes you want to print that address to see
where something lives in memory. In fast_io, the recommended way to
print a pointer is to use the pointervw manipulator.
To use it, include the namespace:
using namespace ::fast_io::iomnp;
Then you can print a pointer like this:
#include <memory>
#include <fast_io.h>
using namespace ::fast_io::iomnp;
int value{42};
int *p = ::std::addressof(value);
println(pointervw(p));
This prints the address stored inside p in a readable, consistent format.
The exact number depends on your system, but conceptually it looks like:
0x0000000000007d30
You can print any pointer this way, including pointer-to-pointer:
int **pp = ::std::addressof(p);
println(pointervw(pp));
Printing pointers is useful for understanding how memory is laid out and how pointers relate to each other.
Key takeaways
- A pointer stores an address, not a value.
T*means “pointer to T”.- Write
int *p;instead ofint* p;to avoid confusion. - Use
::std::addressof(from <memory>) to obtain an address. - Always initialize pointers (use
nullptrif needed). - Pointers themselves are variables and also have their own addresses.
- You can have pointer-to-pointer types like
int **pp. - Use
pointervwfrom::fast_io::iomnpto print pointer values. - This chapter focuses only on syntax; containers come later in Ch5.12.