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
| Feature | Pointer | Reference |
|---|---|---|
| Can be null | Yes (nullptr) | No (must bind to a variable) |
| Can be reassigned | Yes | No (bound once) |
| Syntax for access | *ptr | Direct (like normal variable) |
| Use case | Dynamic memory, arrays | Function 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
deleteon 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.