C++ Pointers
A pointer is a variable that stores a memory address. &x gives the address of x; int* p = &x; stores it in a pointer; *p reaches the value at that address (this is called dereferencing).
Basics
#include <iostream>
int main() {
int x = 10;
int* p = &x;
std::cout << "x = " << x << ", *p = " << *p << "\n";
*p = 25; // changes x
std::cout << "x = " << x << "\n";
int y = 7;
p = &y; // a pointer can point somewhere else
std::cout << "*p = " << *p << "\n";
return 0;
}x = 10, *p = 10 x = 25 *p = 7
Unlike a reference, a pointer can be changed to point at another variable, and it can point at nothing.
nullptr
A pointer that points at nothing holds nullptr. Dereferencing nullptr, or a pointer that was never set, is a serious bug that usually crashes the program. Check first:
#include <iostream>
void show(const int* p) {
if (p == nullptr) {
std::cout << "nothing to show\n";
return;
}
std::cout << "value " << *p << "\n";
}
int main() {
int n = 42;
show(&n);
show(nullptr);
return 0;
}value 42 nothing to show
Pointers and arrays
An array's name is the address of its first element. Adding 1 to a pointer moves to the next element:
#include <iostream>
int main() {
int nums[5] = {1, 2, 3, 4, 5};
int sum = 0;
for (int* q = nums; q != nums + 5; q++) {
sum += *q;
}
std::cout << "sum " << sum << "\n";
std::cout << nums[2] << " " << *(nums + 2) << "\n";
std::cout << "a pointer uses " << sizeof(int*) << " bytes here\n";
return 0;
}sum 15 3 3 a pointer uses 4 bytes here
Pointers to structs and objects
With a pointer to a struct or object, use the arrow -> to reach a member: p->name is the same as (*p).name.
#include <iostream>
#include <string>
struct Pet {
std::string name;
int age;
};
int main() {
Pet cat{"Kitty", 3};
Pet* p = &cat;
p->age++;
std::cout << p->name << " is " << cat.age << "\n";
return 0;
}Kitty is 4
When to use pointers in modern C++
Modern C++ needs raw pointers much less than C does. Use references for parameters, std::vector and std::string instead of raw arrays, and smart pointers (see Smart Pointers) for objects created with new. Raw pointers remain useful as "optional" references that may be nullptr, and when working with C libraries.
Common mistakes
- Using a pointer that was never given an address. Always initialise pointers, with
nullptrif there is nothing yet. - Returning the address of a local variable from a function; it is destroyed when the function returns.
- Confusing
*in a declaration (int* p, "p is a pointer") with*in an expression (*p, "the value p points at").
Practice exercises
- Write a function that takes an
int*and doubles the value, checking fornullptrfirst. - Print the elements of an array in reverse by moving a pointer backwards.
- Write a function that returns a pointer to the largest element of an array.