What Is a Pointer?

A pointer is a variable that stores the memory address of another variable. Instead of holding a value like 42 or "hello", it holds a location — where in memory that value lives.

This might sound abstract, but pointers are what make C++ so fast and flexible. They allow direct memory manipulation, efficient data passing, and dynamic memory allocation.

Declaring and Using Pointers

The * symbol is used to declare a pointer, and the & operator gets the address of a variable:

int age = 30;
int* ptr = &age;   // ptr holds the address of age

std::cout << age;   // Prints: 30
std::cout << ptr;   // Prints: a memory address (e.g., 0x7ffd...)
std::cout << *ptr;  // Prints: 30 (dereferencing)
  • &age — the address-of operator: gives you the memory address.
  • *ptr — the dereference operator: gives you the value at that address.

Pointer Arithmetic

Pointers support arithmetic. When you increment a pointer, it moves by the size of the type it points to — not by 1 byte.

int arr[3] = {10, 20, 30};
int* p = arr;

std::cout << *p;       // 10
std::cout << *(p + 1); // 20
std::cout << *(p + 2); // 30

This is why arrays and pointers are closely related in C++.

Null Pointers

A pointer that doesn't point to any valid memory address should be set to nullptr (in modern C++). Dereferencing a null pointer causes undefined behavior — typically a crash.

int* ptr = nullptr;

if (ptr != nullptr) {
    std::cout << *ptr; // Safe
}

Always initialize your pointers. An uninitialized pointer is a dangling time bomb.

Pointers vs. References

FeaturePointerReference
Can be nullYes (nullptr)No (must bind to a variable)
Can be reassignedYesNo (bound once)
Syntax for access*ptrDirect (like normal variable)
Use caseDynamic memory, arraysFunction parameters, aliases

Dynamic Memory Allocation

One of the most important uses of pointers is managing heap memory with new and delete:

int* dynVal = new int(42);   // Allocate on heap
std::cout << *dynVal;        // 42
delete dynVal;               // Free the memory
dynVal = nullptr;            // Good habit: avoid dangling pointer

Important: Every new must be matched with a delete. Forgetting to do so causes a memory leak.

Common Pointer Mistakes to Avoid

  • Dangling pointers — using a pointer after the memory it points to has been freed.
  • Double delete — calling delete on the same pointer twice.
  • Buffer overflows — writing past the end of an allocated array.
  • Uninitialized pointers — using a pointer before assigning it a valid address.

Modern Alternative: Smart Pointers

In modern C++ (C++11 and beyond), you should prefer smart pointers (std::unique_ptr, std::shared_ptr) over raw pointers for heap memory. They automatically manage memory and help prevent leaks. We'll cover these in depth in the Modern C++ section.

Summary

Pointers are fundamental to understanding C++ at a deep level. Master them, and memory management, data structures, and performance optimization will all make much more sense.