Chapter 5a - Pointers & Memory
What Is a Pointer?β
A pointer is a variable that stores a memory address rather than a value directly. Every variable lives at some address in RAM; a pointer lets you hold and manipulate that address.
int x = 42;
int* ptr = &x; // ptr holds the address of x
cout << x << endl; // 42 (the value)
cout << &x << endl; // 0x7fff... (address of x)
cout << ptr << endl; // 0x7fff... (same address, stored in ptr)
cout << *ptr << endl; // 42 (dereferencing: value at that address)
| Operator | Name | Meaning |
|---|---|---|
&var | Address-of | Get the memory address of var |
*ptr | Dereference | Get the value stored at the address in ptr |
π§ͺ Pointer basics
Addresses change each run. Watch the value 42 stay the same.
Pointer Basicsβ
int a = 10;
int* p = &a;
*p = 20; // change the value of a through the pointer
cout << a << endl; // 20
Pointer Types Must Matchβ
int x = 5;
double y = 3.14;
int* px = &x; // OK
double* py = &y; // OK
// int* pz = &y; // ERROR: type mismatch
Null Pointerβ
A pointer that points to "nothing" is initialized to nullptr (C++11):
int* p = nullptr;
if (p == nullptr) {
cout << "Pointer is null β safe to check before using." << endl;
}
// *p = 5; // undefined behavior β never dereference a null pointer!
Mini quiz β pointer basicsβ
What is a pointer?
1 / 3What does this mean?
&a
Pick an answer to see if you are right.
References vs Pointersβ
A reference is an alias for an existing variable. Unlike a pointer it cannot be null, cannot be reassigned, and uses no extra syntax to dereference.
int x = 10;
int& ref = x; // ref is another name for x
ref = 20;
cout << x << endl; // 20
int* ptr = &x; // ptr holds x's address
*ptr = 30;
cout << x << endl; // 30
| Reference | Pointer | |
|---|---|---|
| Syntax to access | ref | *ptr |
| Can be null | No | Yes |
| Can be reassigned | No | Yes |
| Used for | Function parameters, aliases | Dynamic memory, arrays, optional values |
Pointers and Functionsβ
Passing a pointer to a function lets the function modify the original variable (pass-by-pointer). The same effect can be achieved with a reference (pass-by-reference).
void doubleIt(int* p) {
*p = *p * 2;
}
void tripleIt(int& r) {
r = r * 3;
}
int main() {
int x = 5;
doubleIt(&x);
cout << x << endl; // 10
tripleIt(x);
cout << x << endl; // 30
}
π§ͺ Pass by pointer vs reference
Challenge: double via pointerβ
Finish doubleIt so it doubles the int pointed to by p.
| start | After |
|---|---|
5 | 10 |
3 | 6 |
Dynamic Memory β new and deleteβ
Variables declared normally live on the stack and are automatically destroyed when they go out of scope. new allocates memory on the heap β memory that persists until you explicitly free it with delete.
int* p = new int(42); // allocate an int on the heap, initialize to 42
cout << *p << endl; // 42
*p = 100;
cout << *p << endl; // 100
delete p; // free the heap memory
p = nullptr; // good practice: avoid dangling pointer
Allocating Arrays on the Heapβ
int n = 5;
int* arr = new int[n]; // allocate array of 5 ints
for (int i = 0; i < n; i++) {
arr[i] = i * i;
}
delete[] arr; // use delete[] for arrays (not delete)
arr = nullptr;
Failing to delete heap memory causes a memory leak β the program holds onto RAM it no longer needs.
Pointer Arithmeticβ
Pointers support arithmetic. Adding 1 moves to the next element of the pointed-to type.
int arr[] = {10, 20, 30, 40, 50};
int* p = arr; // points to arr[0]
cout << *p << endl; // 10
cout << *(p+1) << endl; // 20
arr[i] is exactly equivalent to *(arr + i).
π§ͺ Pointer arithmetic
Mini quiz β heap and pointer mathβ
new, delete, and arithmetic
1 / 3Where does this allocate?
new int(42)
Pick an answer to see if you are right.
Pointers to Objectsβ
class Point {
public:
double x, y;
Point(double x, double y) : x(x), y(y) {}
void print() { cout << "(" << x << ", " << y << ")" << endl; }
};
int main() {
Point p1(1.0, 2.0);
Point* p2 = new Point(3.0, 4.0);
p1.print(); // dot operator for stack object
p2->print(); // arrow operator for pointer-to-object
delete p2;
}
ptr->member is shorthand for (*ptr).member.
Smart Pointers (C++11)β
Raw new/delete is error-prone. Smart pointers from <memory> manage heap memory automatically.
unique_ptr β exclusive ownershipβ
#include <memory>
unique_ptr<int> p = make_unique<int>(42);
cout << *p << endl; // 42
In modern C++, unique_ptr replaces almost all manual new/delete.
π§ͺ unique_ptr
Mini quiz β objects and smart pointersβ
Pointers to objects
1 / 3This is the same asβ¦
ptr->member
Pick an answer to see if you are right.
Common Pointer Mistakesβ
| Mistake | What happens |
|---|---|
Dereferencing nullptr | Crash (segfault) |
Dangling pointer β using after delete | Undefined behavior |
Double delete | Undefined behavior / crash |
Using delete on a stack variable | Undefined behavior |
Using delete instead of delete[] on an array | Undefined behavior |
Exercisesβ
Write a function swap(int* a, int* b) that swaps the values of two integers in-place using pointers. Then write the same with references.