How to use dynamic memory in c++ part 1

Hey folks! Today we are going to see how we can utilize dynamic memory in C++. We will also understand why there is a need for dynamic memory and why static memory is not able to fulfill our needs sometimes. So, let’s first understand what memory allocation is.

Memory Allocation

It is the process of allocating physical or virtual memory space to computer programs and services. Memory allocation takes place either before or during program execution. Memory allocations has two categories:

  1. Compile-time or Static Memory Allocation
  2. Run time or Dynamic Memory Allocation

Static Memory Allocation

The compiler allocates static memory for stated variables. The operator’s address helps find the address, which can then be allocated to a pointer. Complier allocates memory during the compilation process.

Dynamic Memory Allocation

Dynamic memory allocation is memory allocation that occurs at the moment of execution (run time). In C++, we allocate dynamic memory by the new operator while calloc() and malloc() function in the case of C. After the value by functions and setting to pointer variables, memory space is allocated dynamically by using these functions. The delete keyword is to deallocate dynamic memory.

What is the need for Dynamic Memory and when?

All memory requirements were calculated prior to the execution of the program by identifying the variables required. However, there may be times when a program’s memory requirements can only be known during runtime. For instance, the user input determines the memory needed. In these situations, applications must dynamically allocate memory, for which the C++ language includes the new and delete operators.

Now let’s discuss new and new[] operator in detail.

Operator new and new[]

The new operator is for allocating dynamic memory. For the series of more than one element, a data type specifier follows new and the number of these within brackets []. It returns a pointer to the start of the newly allocated memory block. 

Syntax

Pointer = new DataType

Pointer = new DataType [noElements]

The first expression is to allocate memory for a single type of element. The second one is to allocate a block (an array) of type “Data Type” elements, where a number of elements are an integer value indicating how many of these there are. Consider the following scenario:

Example
int* studentsMarks;

studentsMarks = new int[5];

In this case, we have a pointer studentsMarks, and the system dynamically allocates space for five elements of type int, where the address of the first element goes to pointer studentMarks. 

Now if we want to access any specific element we can access it via studentsMarks[index] or *(studentMarks + index) where 0 >= index < studentsMarks.length-1 .

The distinction between declaring a regular array and allocating dynamic memory for a block of memory using new is significant. The most significant distinction is that the size of a conventional array must be a constant expression, and so must be decided at the time of program creation, before it is run, but the array created by keyword new, allows any variable value to be used as size during runtime.

The system allocates the dynamic memory needed by our program from the memory heap. Computer memory, on the other hand, is a finite resource that can deplete. As a result, there is no guarantee that the system will allow all requests to allocate memory using operator new.

To check if the allocation was successful, C++ provides two standard mechanisms: One way is to deal with exceptions. In this method, a bad alloc exception occurs on the allocation fails. Exceptions are a strong C++ feature that will cover in more detail later in these courses. For the time being, you should be aware that if this exception occurs and no specified handler handles it, the program will be terminated.

But if you want that if allocation fails, instead of an exception your program continues to execute. What you can do is you can use a special object (notthrow) declared in header <new> with the new keyword. So, if memory allocation fails, it will return nullptr and we can check memory allocation by comparing our pointer with nullptr.  

Code and output

Let’s now see all these concepts in action. You may want to go along with this amazing tutorial, so go ahead create an empty project and open it with the editor of your choice. Create an empty file, In my case it is main.cpp, you can name it what you want and then put the below code in it. 

#include <iostream>
using namespace std;
int main() {
    //Taking array size from user
    int size;
    cout << "Enter size of an array: ";
    cin >> size;

    //declaring and allocating dynamic memory with notthrow object
    int* studentsMarks;
    studentsMarks = new (nothrow) int[size];

    if (studentsMarks == nullptr) {
        cout << "Failed to allocate Memory";
    }
    else {
        //populating array
        for (int i = 0; i < size; i++) {
            cout << "Enter Marks for student " << i + 1 << ": ";
            int marks;
            cin >> marks;
            studentsMarks[i] = marks;
            /*
             * We could have used, *(studentMarks + i) = marks instead of
             * studentsMarks[i] = marks;
             */

        }

        //displaying array
        for (int i = 0; i < size; i++) {
            cout << "Marks for student " << i + 1 << " are: " << studentsMarks[i] << endl;
        }
    }



    return 0;
}

Run the code with the compiler of your choice. We are using GCC which you can download from here.

Output

One last thing I want to mention here about (nothrow) is that it requires carefully validating the pointer value returned after each allocation, this nothrow approach is likely to create less efficient code than exceptions. As a result, at least for crucial allocations, the exception approach is common. Nonetheless, due to its simplicity, the nothrow technique is popular and widely used in most of instances. 

Conclusion

That’s it for dynamic memory in c++. In the next tutorial, we will see how we can use delete and delete[] operators for deallocating memory. 

Scroll to Top