Object Oriented Programming in C++Unit 96 min read
Dynamic Memory Allocation & Pointers: new, delete, malloc, free, pointers, references, and memory leaks
Unit 9 of Object Oriented Programming in C++ covers dynamic memory allocation using pointers, the new/delete operators, memory leaks, dangling pointers, and their role in efficient resource management. Learn how to allocate memory at runtime, avoid common pitfalls, and compare C-style (malloc/free) and C++ (new/delete)
Core Concepts: Pointers and Dynamic Memory
1. What is a Pointer?
A pointer is a variable that stores the memory address of another variable. It allows indirect access to data and enables dynamic memory allocation.
- Syntax:
int x = 10; // Integer variable int* ptr = &x; // Pointer storing address of x cout << *ptr; // Output: 10 (dereferencing)
2. Dynamic Memory Allocation
Unlike static memory (allocated at compile-time), dynamic memory is allocated at runtime using:
- C++ Operators:
new(allocate),delete(deallocate) - C Functions:
malloc()(allocate),free()(deallocate)
Why Use Dynamic Memory?
- Flexible memory usage (e.g., loading game assets of unknown size).
- Avoids stack overflow for large data (e.g., processing NEPSE stock records).
Visual: Memory Allocation in C++
Key Observations:
newreturns a pointer to the allocated memory.deletefrees memory but does not set the pointer tonullptr(risk of dangling pointer).
3. new vs. malloc and delete vs. free
| Feature | new/delete (C++) |
malloc/free (C) |
|---|---|---|
| Memory Type | Handles objects (calls constructors/destructors) | Raw memory blocks |
| Syntax | int* ptr = new int(5); |
int* ptr = (int*)malloc(sizeof(int)); |
| Safety | Type-safe (no casting) | Requires explicit casting |
| Error Handling | Throws std::bad_alloc |
Returns NULL on failure |
Example: Allocating an Array Dynamically
int* arr = new int[5]; // Allocates space for 5 integers
delete[] arr; // Deallocate array (use `delete[]`!)
4. Common Pitfalls and Solutions
a) Memory Leaks
- Cause: Forgetting to
deleteallocated memory. - Example:
void leak() { int* ptr = new int(10); // Memory leaked if not deleted! } - Fix: Always pair
newwithdelete.
b) Dangling Pointers
- Cause: Using a pointer after
delete. - Example:
int* ptr = new int(20); delete ptr; cout << *ptr; // Undefined behavior! - Fix: Set pointer to
nullptrafter deletion:delete ptr; ptr = nullptr;
c) Double Free
- Cause: Calling
deletetwice on the same pointer. - Fix: Check for
nullptrbefore deletion:if (ptr != nullptr) delete ptr;
In the Real World
Pathao’s Ride Allocation
- Uses dynamic memory to manage real-time ride requests. Each request is stored in a linked list node allocated via
new, ensuring scalability during peak hours (e.g., Dashain traffic in Kathmandu).
- Uses dynamic memory to manage real-time ride requests. Each request is stored in a linked list node allocated via
Ncell’s Customer Database
- Dynamically allocates memory for new subscriber records (e.g.,
Customer* newCustomer = new Customer(name, phone)), avoiding static limits.
- Dynamically allocates memory for new subscriber records (e.g.,
Game Asset Loading (e.g., Unreal Engine)
- Loads textures/models at runtime using
new(e.g.,Texture* tex = new Texture("path/to/image.png")), freeing them when the level unloads.
- Loads textures/models at runtime using
Worked Example: Bank Loan Calculator
class Loan {
private:
double principal;
double* interestRates; // Dynamically allocated array
public:
Loan(double p, int years) {
principal = p;
interestRates = new double[years];
// Populate rates (e.g., from NMBL’s current rates)
}
~Loan() { delete[] interestRates; } // Critical to avoid leaks!
};
Trace:
| Step | Action | Memory State |
|---|---|---|
Loan loan(10000, 5); |
Allocates interestRates[5] |
Heap: [0.05, 0.055, ...] |
loan.~Loan() |
delete[] interestRates |
Heap: [Free, Free, ...] |
5. Pointers vs. References
| Feature | Pointers (int*) |
References (int&) |
|---|---|---|
| Initialization | Can be reassigned | Must be initialized once |
| Null Value | Can be nullptr |
Cannot be null |
| Syntax | int* ptr = &x; |
int& ref = x; |
| Use Case | Dynamic memory, arrays | Function parameters (safer) |
Example: Passing by Reference (Safe)
void increment(int& num) { num++; } // Modifies original
int x = 5;
increment(x); // x is now 6
6. Smart Pointers (Bonus: STL Integration)
To avoid manual memory management, use smart pointers from <memory>:
std::unique_ptr: Exclusive ownership (auto-deletes).std::shared_ptr: Shared ownership (reference counting).
Example:
#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(42);
// No need to call delete!
Exam Tip
Memory Management Questions:
- Always show before/after memory states in diagrams (like the Pathao ride queue example).
- Highlight leaks/dangling pointers in code traces.
Common Exam Patterns:
- Short Notes: Define
new/delete,malloc/free, and their differences (2 marks). - Code Debugging: Given a snippet, identify leaks/dangling pointers (5 marks).
- Application: Relate to real systems (e.g., "How would NEPSE use dynamic memory for stock data?").
- Short Notes: Define
Avoid:
- Forgetting
delete[]for arrays. - Using
malloc/freein C++ without casting (prefernew/delete).
- Forgetting
Key Formula to Remember:
- Memory Address Calculation:
For an array
int arr[3],arrpoints to&arr[0],arr + 1points to&arr[1].
Visual Summary:
Based on the PU BE Computer (PU) syllabus for Object Oriented Programming in C++, unit 9.
Discussion
Loading…