Harold Serrano

View Original

Dynamic Memory Allocation in C++

In a video game, when a new character shows up in a scene, memory is allocated for the character. The game developers made sure the game allocates enough memory for the character before you interacted with it. This allocation happens dynamically during runtime, and it is known as Dynamic Memory Allocation.

C++ provides two methods for allocating and deallocating memory: Low-level memory management and an object-oriented memory management. Low-level memory management uses the malloc and free functions to allocate and deallocate memory. Object-oriented memory management uses the new and delete operator instead.

Let's understand how malloc and free works before we learn about the new and delete operator.

Low-Level Memory Allocation

malloc function

The function malloc returns the address of a memory location of a particular size. The syntax is as follows:

my_pointer=(typecast)malloc(size_of_memory);

For example, let's say you need a chunk of memory one integer size long. To request this chunk of memory, you call the malloc function as follows (line 1):

int main(){

    int *p=(int*)malloc(sizeof(int)); //1. Allocating memory

    return 0;
}

Couple of things to note in the example above:

  1. "p" is defined as a pointer. Why? Because only Pointers can receive addresses. The malloc function returns an address location.
  1. malloc returns an address, but it does not know the data type the address will represent. Since the pointer "p" is a pointer to an "int" data type, you must typecast the address with "(int *)".

  2. The argument of malloc represents the memory size you want to allocate. Typically, you use the function "sizeOf()" in the malloc argument to represent a size. In the example above, malloc allocated the representation of an "int" data type.

After memory allocation, you can use the pointer as usual. For example, in the snippet below, the pointer is dereferenced and given the value of five (line 2).

int main(){

    int *p=(int*)malloc(sizeof(int)); //1. Allocating memory

    *p=5; //2. Assigning the value of 5 to p

    return 0;
}

free function

The free function deallocates (gives back) previously allocated memory back to the system. You must always deallocate all previously allocated memory. If you do not, it will lead to memory leaks in your application.

The free function syntax is as follows:

free(my_pointer);

The snippet below deallocates the section of memory allocated in our previous example:

[example 3]

int main(){

    int *p=(int*)malloc(sizeof(int)); //1. Allocating memory

    *p=5; //2. Assigning the value of 5 to p

    free(p); //3. deallocate the memory

    return 0;
}

Object-Oriented Memory Allocation

The functions malloc and free are often used in the C Programming Language. In C++, the operators new and delete are used instead. The new and delete operators perform the same operation as malloc and free, respectively. However, the new and delete operators are often used to allocate memory for user-defined types such as classes.

new Operator

The new operator does the following operations:

  1. It allocates memory for a User Defined Type object.
  2. It initializes the object. i.e., it calls the class constructor. The initialization ensures that the object is properly initialized before use.
  3. It returns an address to the object allocated. As opposed to malloc, you do not need to typecast the return value.

The syntax for the new operator is as follows:

my_pointer=new User_Defined_Type();

The snippet below shows the allocation of a class object using the "new" operator (line 3)

[example 4]

class Student{

private:

public:
    Student(){}; //1. Constructor

    ~Student(){}; //2. Destructor

};

int main(){

    Student *p=new Student(); //3. Allocating memory for the class

    return 0;
}

delete Operator

The delete operator behaves exactly like the free function with a minor difference. It calls the class destructor before deallocating the object.

The syntax of the delete operator is as follows:

delete my_pointer;

The snippet below shows the deallocation of the class object using the "delete" operator (line 4)

[example 5]

class Student{

 private:

 public:
     Student(){}; //1. Constructor

     ~Student(){}; //2. Destructor

 };


 int main(){

     Student *p=new Student(); //3. Allocating memory for the class

     delete p; //4. Deallocating class object memory

     return 0;

 }

Remember this crucial point, the new operator calls the constructor of the class, whereas the delete operator calls the destructor of the class.

Hope this helps