Memory Management In C++ - C++ Programming Tutorial
C++ Course / Memory Management / Memory Management In C++

Memory Management In C++

BLUF: Mastering Memory Management In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Memory Management In C++

C++ is renowned for its efficiency. Learn how Memory Management In C++ enables low-level control and high-performance computing in the tutorial below.

In C++, memory control involves overseeing computer memory and allocating memory to programs to boost system performance. The management of memory is advantageous as it allows for dynamic memory allocation during program execution. It is the programmer's duty to guarantee the efficient utilization and correct release of memory. Improper handling of memory can result in issues such as memory leaks, segmentation faults, dangling pointers, and undefined behavior.

Why is memory management required?

Arrays are designed to hold data of the same type, leading to memory allocation at the point of declaration. However, instances occur where the exact memory needed is unknown until runtime. To prevent this uncertainty, one can declare an array with a predefined maximum size, yet this may result in unused memory space. To counteract this memory wastage, the new operator can be employed to dynamically allocate memory during runtime.

Types of Memory

There are primarily two categories of memory utilized in C++. These are outlined below:

1) Stack Memory

Stack memory is a form of memory allocated by the operating system at compile time in a C++ program. It is responsible for storing variables declared within a function as well as other function-related statements.

Syntax

Stack memory is allocated and released automatically when a function is invoked and exited.

Example

void exampleFunction() {

    int x = 10; // Allocated on the stack

} // x is automatically deallocated when the function ends

C++ Stack Memory Allocation Example

Let's consider a scenario to demonstrate the stack memory allocation process in C++.

Example

Example

#include <iostream>

using namespace std;   //using standard namespace

void stackFunction() {

    int x = 10; // Memory allocated on stack

    cout << "Stack Variable x: " << x << endl;

} // x is automatically deallocated when function exits

int main() {   //main function

    stackFunction();

    // The variable x no longer exists after the function call

    return 0;

}

Output:

Output

Stack Variable x: 10

Explanation:

In this instance, the variable x is assigned space in the stack within the stackFunction routine. Subsequently, the memory allocated for x is automatically deallocated upon the function's completion. There is no need for manual memory handling such as using new or delete.

2) Heap Memory

In C++, heap memory is referred to as dynamic memory. It constitutes a segment of memory that can be adjusted in size as needed. Unlike stack memory, heap memory requires manual management by the programmer. Though slower in speed than stack memory, heap memory allows for dynamic allocation and deallocation of memory using the new and delete operators. This capability to adjust memory allocation during program execution enhances the efficiency of C++ programs utilizing heap memory.

C++ Heap Memory Example

Let's consider a scenario to demonstrate the heap memory in C++.

Example

Example

#include <iostream>

using namespace std;  //using standard namespace

int main() {   //main function

    int* ptr = new int;  // Allocating memory for one integer

    *ptr = 25;  // Assigning value

    cout << "Value stored in heap memory: " << *ptr << endl;

    // Free the allocated memory

    delete ptr;

    return 0;

}

Output:

Output

Value stored in heap memory: 25

Explanation:

In this instance, we have utilized the 'new int' keyword to dynamically allocate memory from the heap rather than the stack. Subsequently, we have assigned the pointer 'ptr' on the stack to point to an integer stored in the heap.

Memory Management Operators

In the C++ programming language, we employ the malloc or calloc functions to dynamically assign memory during program execution. Subsequently, the free function is utilized to release the dynamically allocated memory. Alongside these functions, C++ incorporates unary operators like new and delete for the same purposes, allowing for memory allocation and deallocation.

New Operator

A fresh operator is employed for object instantiation, whereas the delete operator is utilized for object deletion. An object created with the new operator remains in existence until explicitly removed using the delete operator. Consequently, the object's lifespan is independent of the program's block structure.

Syntax

It has the following syntax:

Example

pointer_variable = new data-type

The above syntax is used to create the object using the new operator. In the above syntax,

  • pointer_variable: It represents the name of the pointer variable.
  • new: It represents the operator.
  • data-type: It defines the type of the data.

For Example:

Example

int *p = new int;

In this format, we allocate memory for a sole integer by employing the new operator and then save the memory location in the integer pointer p. It is also possible to specify the allocated memory with an initial value.

Example

int *p = new int (25);

C++ New Operator Example

Let's consider a scenario to demonstrate the functionality of the new operator in C++.

Example

Example

#include <iostream>

using namespace std;  //using standard namespace

int main() {  // function

    // Using new operator to allocate memory dynamically

    int* num = new int; // Allocate memory for one integer

    *num = 25;   // Assign value to that memory

    cout << "Number: " << *num << endl;

    // Free the allocated memory

    delete num;

    return 0;

}

Output:

Output

Number: 25

Explanation:

In this instance, a fresh integer is declared to reserve space on the heap for a solitary integer. Subsequently, setting *num = 25 assigns the number 25 to the reserved memory. Ultimately, the delete num operator releases the memory to prevent any memory leaks.

How to create a single dimensional Array in C++?

As it's commonly understood, the new operator is employed to allocate memory for various data types, including user-defined data types like arrays, structures, unions, and more. Below is the syntax for creating a one-dimensional array:

Example

pointer-variable = new data-type[size];

For Examples

Example

int *a1 = new int[8];

In this instance, we've established an integer array with a length of 8, where p[0] corresponds to the initial element, p[1] corresponds to the second element, and so forth.

Delete Operator

In C++, the delete operator is primarily employed to free up dynamically allocated memory. When memory is no longer needed, it must be deallocated to free it up for other uses. This can be accomplished using the delete operator.

Syntax

It has the following syntax:

Example

delete pointer_variable;

The dynamically allocated array can also be deallocated from memory by utilizing the syntax below:

Example

delete [size] pointer_variable;

In this context, we must indicate the dimension that specifies the quantity of elements that need to be deallocated. The limitation of this format is the necessity to keep track of the array's size.

Example

delete [ ] pointer_variable;

C++ Delete Operator Example

Let's consider a scenario to demonstrate the use of the delete operator in C++.

Example

Example

#include <iostream>  

using namespace std;     //using standard namespace

int main()   //main function

{  

int size;  // variable declaration  

int *arr = new int[size];   // creating an array   

cout<<"Enter the size of the array : ";     

std::cin >> size;    //   

cout<<"\nEnter the element : ";  

for(int i=0;i<size;i++)   // for loop  

{  

cin>>arr[i];  

}  

cout<<"\nThe elements that you have entered are :";  

for(int i=0;i<size;i++)    // for loop  

{  

cout<<arr[i]<<",";  

}  

delete arr;  // deleting an existing array.  

return 0;  

}

Output:

Output

Enter the size of the array: 5

Enter the element: 1

2

3

4

5

The elements that you have entered are: 1,2,3,4,5,

Explanation:

In this instance, an array has been generated utilizing the new operator. Subsequently, the application will prompt the user to input the array's size during runtime. Upon finishing all tasks, the object is removed using the command delete arr.

Advantages of the New Operator

There are several advantages of the new operator over malloc function:

  • It does not use the sizeof operator because it automatically computes the size of the data object.
  • It automatically returns the correct data type pointer, so it does not need to use typecasting.
  • Like other operators, the new and delete operator can also be overloaded.
  • It also allows us to initialize the data object while creating the memory space for the object.
  • Advantages of the Delete Operator

Several advantages of the delete operator in C++ are as follows:

  • Without using the delete operator, dynamically allocated memory stays reserved even after it's no longer required.
  • It provides us full control over when and how memory is released in C++.
  • When the delete operator is called on a pointer to an object , the destructor of the object is also called automatically.
  • It makes our program more memory-efficient and suitable for large-scale or resource-constrained systems.
  • C++ Memory Management MCQs

1) What happens to a variable allocated on the stack when the function in which it is declared exits?

  • It should be manually deleted
  • It is automatically deallocated
  • It becomes a global variable
  • It causes a memory leak

2) Which of the following syntax correctly allocates and deallocates an array on the heap?

  • int* arr = new int(5); delete arr;
  • int* arr = new int[5]; delete arr;
  • int arr[5]; delete arr;
  • int arr = malloc(5 sizeof(int)); free(arr);

3) Which smarcpp tutorialer should be used when only one owner should manage the lifetime of a dynamically allocated object?

  • std::shared_ptr
  • std::weak_ptr
  • std::unique_ptr
  • std::auto_ptr

4) What will happen if delete is called on a pointer twice (double delete)?

  • It frees the memory safely
  • It causes a compilation error
  • It results in undefined behavior
  • It reinitializes the memory

5) What is the purpose of std::weak_ptr in smarcpp tutorialer management?

  • To create a non-owning reference and avoid circular dependencies
  • To increase reference count
  • To manage exclusive ownership
  • To allocate memory on the heap

a) To generate a reference without ownership and prevent circular dependencies

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience