Memory Management in C++
COS2611 - Programming: Data Structures · Dynamic Memory Allocation
Memory Management in C++
Memory management is a critical aspect of programming in C++. It deals with how memory is allocated and deallocated during the execution of a program. This is essential for efficient resource use and preventing memory leaks, which can lead to performance issues.
Static vs Dynamic Memory Allocation
In C++, memory can be allocated in two main ways: static and dynamic.
- Static Memory Allocation: Memory is allocated at compile time. The size of the memory must be known before compilation. For example, when you declare an array like
int arr[10];, the memory for the array is allocated when the program is compiled. - Dynamic Memory Allocation: Memory is allocated at runtime. This allows for more flexibility, as you can request memory based on the program's needs. Dynamic memory allocation is done using pointers and functions like
newanddelete.
Remember: Use dynamic memory allocation when the size of data structures cannot be determined at compile time.
Dynamic Memory Allocation in C++
Dynamic memory allocation in C++ is performed using the new operator. This operator allocates memory on the heap, which is a region of free memory available for dynamic allocation. When you allocate memory using new, you must also deallocate it using delete to avoid memory leaks.
Allocating Memory
To allocate memory for a single variable, use the following syntax:
int* my_var = new int;This code allocates memory for an integer and assigns its address to the pointer my_var.
Allocating Memory for Arrays
To allocate memory for an array, use the following syntax:
int* my_array = new int[10];This code allocates memory for an array of 10 integers. The pointer my_array now points to the first element of the array.
Tip: Always check if the memory allocation was successful. If new fails, it returns nullptr.
Deallocating Memory
To free the memory allocated with new, you use the delete operator. For a single variable, the syntax is:
delete my_var;For an array, use:
delete[] my_array;It is important to match each new with a corresponding delete to prevent memory leaks.
Watch out: Forgetting to deallocate memory can lead to memory leaks, while using delete on memory not allocated with new can cause undefined behaviour.
Example: Dynamic Memory Allocation
Let’s look at a complete example that demonstrates dynamic memory allocation and deallocation.
#include <iostream> using namespace std; int main() { int* my_array = new int[5]; // Allocate memory for an array of 5 integers for (int i = 0; i < 5; i++) { my_array[i] = i * 10; // Initialize the array } for (int i = 0; i < 5; i++) { cout << my_array[i] << " "; // Print the array } cout << endl; delete[] my_array; // Deallocate memory return 0; }This program allocates an array of 5 integers, initializes them with values, prints the values, and then deallocates the memory.
Using Pointers with Dynamic Memory
Dynamic memory allocation is often used in conjunction with pointers. A pointer is a variable that stores the address of another variable. When you allocate memory dynamically, you typically use a pointer to manage that memory.
Pointer Basics
To declare a pointer, use the following syntax:
int* ptr;This declares a pointer variable ptr that can point to an integer. After allocating memory, you can access the allocated memory using the pointer.
Example: Pointer and Dynamic Memory
Here is an example that combines pointers with dynamic memory allocation:
#include <iostream> using namespace std; int main() { int* ptr = new int; // Allocate memory for a single integer *ptr = 42; // Assign a value to the allocated memory cout << "Value: " << *ptr << endl; delete ptr; // Deallocate memory return 0; }This program allocates memory for a single integer, assigns the value 42 to it, prints the value, and then deallocates the memory.
Remember: Always set pointers to nullptr after deleting them to avoid dangling pointers.
Common Memory Management Errors
When working with dynamic memory in C++, there are several common errors to watch for:
- Memory Leaks: Forgetting to deallocate memory leads to memory leaks. Use tools like Valgrind to detect memory leaks in your programs.
- Dangling Pointers: A pointer that points to deallocated memory is a dangling pointer. Accessing it leads to undefined behaviour. Always set pointers to
nullptrafter deletion. - Double Deletion: Deleting the same memory twice can cause crashes. Ensure that you only delete memory once.
Watch out: Always check your pointer before dereferencing it. Dereferencing a nullptr leads to runtime errors.
Best Practices for Memory Management
To manage memory effectively in C++, follow these best practices:
- Always pair
newwithdeleteandnew[]withdelete[]. - Use smart pointers, such as
std::unique_ptrandstd::shared_ptr, to automate memory management and reduce the risk of memory leaks. - Regularly review your code for memory management issues, especially in larger projects.
Summary
- Static memory allocation happens at compile time, while dynamic memory allocation occurs at runtime.
- Use the
newoperator to allocate memory dynamically anddeleteto deallocate it. - Always check for successful memory allocation and avoid memory leaks by pairing
newwithdelete. - Be aware of common errors such as memory leaks, dangling pointers, and double deletion.
Check your understanding
- What is the difference between static and dynamic memory allocation?
- How do you allocate memory for an array in C++?
- What happens if you forget to deallocate memory that was allocated with
new? - What is a dangling pointer and how can you avoid it?