C++ Pointers Explained for Beginners: Address, Dereference, and Common Bugs
이 글의 핵심
A practical guide to pointers: from addresses and dereferencing to swap, dynamic memory, pointer arithmetic, smart pointers, and the const-pointer patterns that confuse beginners.
Pointers as street addresses
Analogy: A variable is a house (the storage); a pointer is the address telling you where that house is.
variable = house (where data lives)
pointer = address (where to find the house)
Core ideas
Variables and addresses
int age = 25; // variable: holds a value
int* ptr = &age; // pointer: holds an address
// &age : address of age
// ptr : stores that address
Picture:
Address Name Value
0x1000 age 25
0x2000 ptr 0x1000 (address of age)
Declaring pointers
int* ptr;
double* ptr2;
char* ptr3;
// Asterisk placement is style-only:
int *ptr;
int * ptr;
Address-of &
int x = 10;
int* ptr = &x;
std::cout << x; // 10
std::cout << &x; // address
std::cout << ptr; // same address as &x
Dereference *
int x = 10;
int* ptr = &x;
std::cout << *ptr; // 10
*ptr = 20;
std::cout << x; // 20
Practical examples
Example 1: swap
void swap_wrong(int a, int b) {
int temp = a;
a = b;
b = temp;
}
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 10, y = 20;
swap_wrong(x, y); // unchanged
swap(&x, &y); // swapped
}
Example 2: Arrays and pointers
int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr; // array name decays to pointer to first element
std::cout << *ptr; // 1
std::cout << *(ptr+1); // 2
std::cout << ptr[2]; // 3
Frequent mistakes
Uninitialized pointers
int* ptr;
*ptr = 10; // UB
int* ptr = nullptr;
// or bind to a valid int
Confusing pointer vs pointed-to value
int x = 10;
int* ptr = &x;
*ptr = 20; // OK
Dangling pointers
Do not store addresses of locals past their lifetime; use heap with clear ownership or smart pointers.
Pointers vs references
References alias an existing object; pointers can be null and reseated.
Dynamic memory
new / delete
int* p = new int;
*p = 10;
delete p;
int* arr = new int[100];
delete[] arr;
Leaks
Every new needs a matching delete (or use smart pointers).
Pointer arithmetic
For T* p pointing into an array, p+1 advances by sizeof(T) bytes logically—use with care.
Why use pointers?
- Out parameters and C APIs
- Optional arguments (
nullptr) - Dynamic allocation (prefer containers/smart pointers in app code)
FAQ highlights
- Why scary? Small mistakes → crashes/UB.
- nullptr: the null pointer literal.
- Arrays: array name points to first element;
a[i]↔*(a+i). - Double pointers: pointer to pointer—advanced but same rules.
- Modern C++:
std::unique_ptr,std::shared_ptr, references, containers.
Advanced: const and pointers
int x = 1;
const int* p1 = &x; // cannot modify *p1 through p1
int* const p2 = &x; // cannot point p2 elsewhere
const int* const p3 = &x;
Mnemonic: const before * → “pointee const”; const after * → “pointer const.”
Advanced: void*, alignment, uintptr_t
When interfacing with C APIs, cast void* back with static_cast to the correct type; use uintptr_t for address-as-integer tricks.
Debugging (ASan / GDB)
| Situation | Tool |
|---|---|
| Random crashes | AddressSanitizer (-fsanitize=address) |
| Heap corruption | ASan + UBSan (where applicable) |
| Leaks | LeakSanitizer (with ASan), Valgrind |
| Where it broke | GDB watch, bt |
Linked list sketch (educational)
The Korean article shows Node with next and push_front/free_list—same as classic K&R style; production code prefers std::unique_ptr or containers.
Related posts (internal links)
- Stack vs heap
- Observer pointer
- Functions
Practical tips
Debugging
- Fix warnings first; reproduce minimally.
Performance
- Pointer dereference is rarely the bottleneck—memory access patterns and caches dominate.
Code review
- Ownership and lifetime rules clear?
Practical checklist
Before coding
- Is a pointer the right abstraction?
While coding
- Initialized? Paired new/delete or smart pointer?
During review
- No dangling/alias bugs?
Keywords (search)
C++, pointers, address, dereference, nullptr, beginner
Related posts
- Classes and objects