Dynamic Memory Allocation in C++

Below is a basic memory architecture used by any C++ program:

Memory Management in C++

  • Code Segment: Compiled program with executive instructions are kept in code segment. It is read only. In order to avoid over writing of stack and heap, code segment is kept below stack and heap.
  • Data Segment: Global variables and static variables are kept in data segment. It is not read only.
  • Stack: A stack is usually pre-allocated memory. The stack is a LIFO data structure. Each new variable is pushed onto the stack. Once variable goes out of scope, memory is freed. Once a stack variable is freed, that region of memory becomes available for other variables. The stack grows and shrinks as functions push and pop local variables. It stores local data, return addresses, arguments passed to functions and current status of memory.
  • Heap: Memory is allocated during program execution. Memory is allocated using new operator and deallocating memory using delete operator.

Allocation of Heap Memory using new Keyword

Here we will learn how to allocate heap memory to a variable or class object using the new keyword.

Syntax:

datatype pointername = new datatype

For example:

int *new_op = new int;
// allocating block of memory
int *new_op = new int[10];

If enough memory is not available in the heap it is indicated by throwing an exception of type std::bad_alloc and a pointer is returned.




Deallocation of memory using delete Keyword

Once heap memory is allocated to a variable or class object using the new keyword, we can deallocate that memory space using the delete keyword.

Syntax:

delete pointer variable

For example:

delete new_op;

The object's extent or the object's lifetime is the time for which the object remains in the memory during the program execution. Heap Memory allocation is slower than a stack. In heap there is no particular order in which you can allocate memory as in stack.


Understanding Memory Leak in C++

Memory leak happens due to the mismanagement of memory allocations and deallocations. It mostly happens in case of dynamic memory allocation. There is no automatic garbage collection in C++ as in Java, so programmer is responsible for deallocating the memory used by pointers.

Misuse of an elevator in a building in real life is an example of memory leak. Suppose you stay in an apartment building which has 19 floors. You wanted to go to 10th floor so you pressed the button to call the lift. The status of elevator is displaying as basement for 20 minutes. Then you realize that something is wrong, and upon investigating you find out that kids were playing in basement and they had blocked the lift door.

Similarly once a pointer is done with its operations it should free the memory used by it. So that other variables can use the memory and memory can be managed effectively.

By using the delete keyword we can delete the memory allocated:

For example:

*ex= new Example();
delete ex;

But in the above example dangling pointer issue can happen. Wait! what is a dangling pointer?


What is a Dangling Pointer?

A pointer pointing to a memory location of already deleted object is known as a dangling pointer.

Memory Management

  • In the first figure pointer points to a memory location 1100 which contains a value 25.
  • In the second figure pointer points to a memory location where object is deleted.

Dangling pointers arise due to object destruction, when an object reference is deleted or deallocated, without modifying the value of the pointer, so the pointer will keep on pointing to the same memory location. This problem can be avoided by initializing the pointer to NULL.

For example:

*ex = new Example();
Delete ex;
// assigning the pointer to NULL
ex = NULL;

What is a Smart Pointer?

Smart Pointer is used to manage the lifetimes of dynamically allocated objects. They ensure proper destruction of dynamically allocated objects. Smart pointers are defined in the memory header file.

Smart pointers are built-in pointers, we don't have to worry about deleting them, they are automatically deleted.

Here is an example of a smart pointer:

S_ptr *ptr = new S_ptr();
ptr->action();
delete ptr;