C++ Pointers & Memory

C++ gives you direct access to memory through pointers — powerful but requiring care. Modern C++ provides smart pointers that manage memory automatically.

What is a Pointer?

A pointer stores the memory address of another variable:

CPP
int x = 42;
int *ptr = &x;       // ptr stores the address of x

cout << *ptr << endl; // 42 — dereference: get the value at that address
cout << ptr << endl;  // 0x7fff... — the address itself
Syntax Meaning
int *ptr Declare a pointer to int
&x Get the address of x
*ptr Get the value at the address (dereference)

Heap Allocation

CPP
// Allocate on the heap (manual management)
int *p = new int(10);
delete p;           // must free manually!

int *arr = new int[5]{1, 2, 3, 4, 5};
delete[] arr;       // must use delete[] for arrays

Problem: if you forget delete, you have a memory leak. If you delete twice, you have undefined behaviour.

Smart Pointers (Modern C++ — Prefer These)

Smart pointers free memory automatically — no manual delete needed:

unique_ptr (Sole Ownership)

CPP
#include <memory>

auto p = std::make_unique<int>(42);
// Automatically freed when p goes out of scope

auto arr = std::make_unique<int[]>(5);
arr[0] = 1;

Rule: use unique_ptr by default — it has zero overhead.

shared_ptr (Reference Counted)

CPP
auto s1 = std::make_shared<string>("Hello");
auto s2 = s1;  // reference count = 2

// Freed when the last shared_ptr is destroyed

weak_ptr (Non-Owning Observer)

CPP
std::weak_ptr<string> weak = s1;
if (auto locked = weak.lock()) {
    cout << *locked << endl;  // still alive
}

nullptr

CPP
int *p = nullptr;  // modern replacement for NULL

if (p != nullptr) {
    cout << *p << endl;
}

Pass by Pointer vs Reference

CPP
void byRef(int &n)  { n *= 2; }   // cannot be null, always valid
void byPtr(int *n)  { *n *= 2; }  // can be null, reseatable
Feature Reference (&) Pointer (*)
Can be null ❌ ✅
Can be reseated ❌ ✅
Syntax at call site func(x) func(&x)
Syntax in function n *n

Rule of thumb: use references when possible; use pointers only when nullability or ownership semantics require it.

Memory Leaks

CPP
// ❌ Memory leak — never deleted
int *leak = new int(42);

// ✅ Smart pointer — automatically freed
auto safe = std::make_unique<int>(42);

Tips

  • Never use new/delete in modern C++ — use smart pointers instead.
  • Use unique_ptr as your default smart pointer.
  • Use shared_ptr only when multiple owners need the same object.
  • Use make_unique and make_shared instead of raw new.

🎉 You have completed the C++ course! The next step is to build something — a CLI tool, a game with SFML/SDL, or contribute to an open-source project.