C++ provides two primary mechanisms for indirectly accessing and modifying data:
- Pointers, which store memory addresses
- References, which act as aliases for existing variables
Though both can be used to access other variables, they serve different purposes, with distinct syntax, behavior, and safety characteristics.
What is a Pointer?
A pointer is a variable that holds the address of another variable.It enables indirect access and manipulation of data stored in a different memory location by referencing its address.
-
int* ptr: Declares a pointer to anint. It can store the address of an integer variable. -
&x: The address-of operator (&) is used to get the memory address of a variablex.
Visualizing a pointer
Pointer Dereferencing
Dereferencing a pointer using (*) gives access to the actual variable it points to, allowing you to read or modify it directly.
Null Pointers
Pointers can point to nothing, a null value
Pointer Arithematic
int* ptr = arr;
This means ptr points to the first element of the array. In C++, the array name (arr) automatically acts like a pointer to its first element.
Accessing Elements Using Pointer Arithmetic
-
*ptrgives the value at the first element. -
*(ptr + 1)moves the pointer one step ahead and accesses the second element. - You can keep doing
*(ptr + i)to accessarr[i].
Accessing Class Members via Pointer
ptr->x and ptr->show() access members through the pointer using the -> operator.
What is a Reference?
A reference is an alias for another variable. Once initialized, it cannot be changed to refer to another object.
- Always initialized during declaration
- No
nullptr, no reassignment - Looks like a variable, behaves like an alias
- References are used to avoid copying of data, making the function more efficient, especially with large objects.
- They allow functions to modify the original variable directly.
- Pass-by-reference is useful when:
- You want to avoid performance overhead of copying.
- You need the function to update the caller's variable.
Passing by Reference Without Modification
Using const std::string& means the function receives the original variable by reference, but promises not to modify it. This ensures safety while avoiding the overhead of copying.
When to Use Pointers
- Dynamic memory allocation
- Nullable objects
- Data structures (linked lists, trees)
- Interfacing with C libraries
- Arrays and pointer arithmetic
When to Use References
- Function arguments/return types
- Operator overloading
- Avoiding copies
- Cleaner syntax for indirection
Advanced Topics
Working with Pointers and Custom Classes in C++
In C++, when you create objects using new, you get a pointer to that object. You must manually delete it to free memory.
new returns a pointer to the heap-allocated object.
You must call delete to avoid memory leaks.
Returning by Reference
Allows function to return modifiable values:
Never return a reference to a local variable causes dangling reference.
Example (Dangling Reference):
-
xis a local variable, so it gets destroyed whengetRef()ends. - Returning a reference to it creates a dangling reference, leading to undefined behavior.
Pointers to Pointers
You can use a pointer to a pointer (int**) to dynamically create and manage 2D arrays.
Smart Pointers (Modern C++)
Smart pointers are class templates in C++ that manage the lifetime of dynamically allocated objects. Unlike raw pointers (int*), they automatically free memory when it's no longer needed, helping prevent:
- Memory leaks
- Dangling pointers
- Manual delete calls
They're part of the C++ Standard Library (since C++11) and live in the <memory> header.
Types of Smart Pointers
std::unique_ptr
Owns a resource exclusively (no other pointer can point to it). Automatically deletes the object when it goes out of scope.
std::shared_ptr
Allows multiple pointers to share ownership of a dynamically allocated object. Internally uses reference counting.
std::weak_ptr
A non-owning smart pointer that observes a shared_ptr without affecting its reference count. Prevents cyclic references.
A weak_ptr does not own the object, so it can’t access it directly.To use the object safely, you use the .lock() method.
.lock() does two things:
- Checks if the object still exists (hasn't been deleted).
- Returns a
shared_ptrto access the object only if it's still alive.
What is Reference Count in Smart Pointers?
Reference count is a number that keeps track of how many shared_ptrs are pointing to the same object.
This count:
-
Increases when a
newshared_ptris created from an existing one. -
Decreases when a
shared_ptris destroyed or reset.
When the reference count drops to zero, it means no one is using the object anymore, so it gets automatically deleted — no manual delete() needed


















Top comments (0)