QnA on Memory Management in C/C++






Memory management is an crucial part of the C++ programming and it is necessary that we should keep our concepts clear on this topic. Below are some set of questions based on this topic to brush the skill and also helpful for technical interviews.

  • Q:  What are the operators and function available in C++ for dynamic memory allocation and deallocation ?
    Ans:  Available operators and functions available for memory management are:-

    • new - Operator to allocate new memory block in heap.

    • delete - Operator to release and clear allocated memory block from heap.

    • malloc() - Function to allocate new memory block in heap.

    • calloc() - Function to allocate the memory block

    • realloc() - Dynamically change the memory allocation of the previously allocated memory block

    • free() - Function to release and clear allocated memory block from heap.

  • Q:  Explain the differences between malloc(), calloc() and realloc().
    Ans: 
    Malloc- Features of malloc() are:

    • Used for dynamic memory allocation.

    • It allocates a single block of memory with a specific size.

    • It only allocates the memory block and will not initialized the same. It means the allocated memory space contains the garbage values.

    • It returns the void pointer which needs to be casted into the type as required.

    • Ex.
                int* var = (int*) malloc(10*sizeof(int));
      Here we are calling the malloc() with argument as the size of byte. As we know size of integer in 4 byte, so here we are requesting the total of 10*4 = 40 bytes of memory space. In return malloc will reserve that much amount of space in the memory and will return the void pointer which is pointing to that memory location. Finally we are type-casting this void pointer to the type integer pointer and storing it into our pointer variable named "var" of type int.

    Calloc- features of calloc() are:

    • Used for dynamic memory allocation.

    • It performs the contiguous memory allocation.

    • It will initialize the allocated memory block with value 0.

    • Ex.
                int* var = (int*) calloc(10, sizeof(int));
      Here it will take two arguments, one is the number of elements and another is the size of each element. Here it will allocate the array of 15 elements each of 4 bytes(size of int).

    Realloc- features of Realloc() are:

    • Used for dynamically change the memory allocated previously with malloc() or calloc().

    • If previously allocated memory is insufficient then we can use realloc() to reallocate the new additional memory space. Also in doing so the data present
      in previous allocated memory space will not be effected and newly allocated memory space will be initialized with garbage value.

    • Ex.
                int* var = (int*) malloc(10*sizeof(int));
                var = realloc(var, 20*sizeof(int));

    Diagrammatically representation for malloc, calloc and realloc -
    page1

  • Q:  Differentiate between new and malloc?
    Ans:  Even tough both new and malloc server the similar purpose of dynamic memory allocation but still there are some point which differentiate
    them from each other.

    • new is an operator while malloc is a library function.

    • malloc() needs the typecasting into required type as it always returns a void pointer while allocating memory, but this is not the case with new operator.

    • malloc() only allocates the memory space but not initializes it so it contains the garbage values until a valid value will be stored in that space. On the other
      hand new will allocate the memory space and initializes it with zero.

    • In case of new, the constructor will be invoked but this won't happen in case of malloc()

  • Q:  Explain the difference between free() and delete?
    Ans:  The differences are as below :-

    • delete will invoke the destructor but free() won't.

    • delete is an operator but free() is a library function.

  • Q:  What is new[] and delete[] ?
    Ans:  Whenever we need to allocate memory for the array of objects we have to use the use the "new[ ]". And in order to deallocate that memory space we need
    to use "delete[ ]". It should be keep in mind that in order to free the memory space allocated for array of object we always have to use delete[], because only
    using delete will not works here and the acquired memory will not be deallocated porperly.
    Ex.

                        
                          class testClass{
                            ..
                            ..
                          };
                            
                          void main(){
                            ..
                            testClass* ptr = new testClass[5];
                            ..
                            ..
                            delete[] testClass;
                          }
                        
                      

  • Q:  What happens if we forgot to free the allocated memory after using malloc() ?
    Ans:  The memory block which is allocated using malloc() will not be deallocated on its own, we must take care of its deallocation using the free() function. If
    we forgot to free the memory space then it might result in the "memory leak" issue. If our program runs in the background task for a long interval and also
    periodically allocates the memory then at a certain period of time we will run out of the available memory and might cause the program to crash. So it's a
    good practice to free the allocated memory whenever we are using malloc().

  • Q:  What is Static and Dynamic Memory Allocation ?
    Ans: 
    Static Memory Allocation :- In static memory allocation, memory is allocated by the compiler during compile time. It is like permanent memory allocation to
    the variable, so we cannot manually free or reuse that allocated space in the memory till the time the program is in execution. Once the life of the program
    ends or the execution of the block of code(inside which static memory is allocated) comes to an end that memory space will automatically get free. In the
    static memory allocation, the memory is allocated in the "stack" part of the memory. This is also known as compile-time memory allocation.
    Some of the example scenarios when static memory allocation is used-

    • When local variables are created.

    • When a function call is done then it will save the current instance in the stack.


    Dynamic Memory Allocation :- In dynamic memory allocation, memory is allocated at the time of execution or simply said at run time. It is also known as
    run-time memory allocation. In this memory is allocated in the "heap" part of the memory. We can also free and reuse the allocated memory in this.

  • Q:  Explain the memory layout structure of a C/C++ program.
    Ans:  Memory layout structure of a C/C++ program can be further divided into below segments:-

    • Text Segment -
      It is that part of the memory where the executable instruction or the code will be stored. It is also known as code segment.

    • Initialized data segment -
      It is the part of the memory where the initialized static variables and global variables are stored.

    • Uninitialized data segment -
      This part of memory is used to store the uninitialized static variables and global variables. It is also known as "bss" segment which means "block
      started by symbol".

    • Heap -
      This memory segment is used during dynamic memory allocation. Whenever the memory allocation is made using the malloc(), calloc(), realloc()
      or new, the memory is allocated in this part of the memory. Also free() or delete is used to free the previously allocated memory form the heap.

    • Stack -
      Stack is the area where automatic variables are stored and also the information that is saved each time when a function is called. When a function
      is called, the information such as returning address, machine register, etc. are saved on the stack temporarily. It works in the Last-In-First-Out (LIFO)
      fashion, which means the variable which is inserted last in the stack is the first one when we do pop-out from the stack. Stack generally grows
      downwards in the direction towards the lower address of the memory.

    Diagrammatical representation of the memory layout is as below -
    page1

  • Q:  What is a "Core Dump" or "Segmentation Fault" error ?
    Ans:  "Core dump" or "Segmentation Fault" is the type of error that indicates memory corruption. Whenever a code is trying to perform the write operation
    on a read-only memory or a pointer trying to access the memory location which is already freed then it will result in this type of error. It may result
    the program to crash.

  • Q:  What is a "Wild Pointer" ?
    Ans:  Wild pointers are nothing but the uninitialized pointers. These are the pointer that is not initialized by the user and point to some arbitrary memory
    location. Using this pointer will be very harmful as it may result in memory corruption or a program crash.

  • Q:  From the example explain the wild pointer and the method to overcome it.
    Ans:  Example of a wild pointer-

                        
                          void main(){
                            int* ptr;
                            *ptr = 5;
                          }
                        
                      

    Here "ptr" is the pointer which is not initialized during its declaration and is pointing to some unknown memory location. So it behaves as a wild pointer
    and in the next line when we are assigning the value 5 to is it may corrupt that memory location.

    Methods to overcome the wild pointer issue -
    By using the dynamic memory allocation.

                          
                            void main(){
                              int* ptr = (int*) malloc(sizeof(int));
                              *ptr = 5;
                            }
                          
                        

    Now the pointer ptr is pointing to a specific memory location which we had allocated for it and in the next line we are storing the value 5 to that location.
    So this will not be a wild pointer.

    Another method is by using "addressOf" operator

                          
                            void main(){
                              int* ptr;
                              int var = 5;
                              ptr = &var;
                              *ptr = 10;
                          }
                          
                        

    Here we make the pointer ptr to point to the address of the variable var using the addressOf ('&') operator. So this is ok and it won't return the error when
    we further use this pointer to access the value of var as we are doing here for updating its value to '10'.

  • Q:  Give the syntax to allocate and deallocate an array of objects ?
    Ans:  We can allocate an array of objects using the new operator along with the "[n]" in the new expression. Also we have use [] in the delete statement
    while deallocating the array of objects.
    Ex.
              MyClass* ptr = new MyClass[10];
              ...
              ...
              delete[ ] ptr;
    Here we are creating the array of 10 objects of the class 'MyClass' using the new and at last deallocating it using delete[ ].

  • Q:  What happens if we forget the "[]" when deleting array allocated via new MyClass[n] ?
    Ans:  In this case, neither a compile-time nor a run-time error message will be generated by the compiler. But the Heap corruption is likely to be possible.
    So, it's the responsibility of the programmer to use delete[] to correctly deallocate the memory space.

  • Q:  Can we use "delete" to free the memory space allocated by malloc()? Or use free() on memory space allocated by "new" ?
    Ans:  No! it is not advisable to mix up malloc() & delete or new & free(). Sometimes luckily it might work but it can also lead to some serious memory corruption
    issues. Basically, malloc()/free() and new/delete operates at different levels - raw memory vs. constructed objects.

    The C++'s operators new and delete guarantee proper construction and destruction, where constructors or destructors are invoked. But the C-style library
    functions malloc() and free() don't ensure that. Suppose we create a memory space using new operator and delete it using free(), then in that case destructor
    won't be invoked and the acquired memory and resources will be released. So, this might result in the memory leak issue.

    Also, there is no guarantee that the mechanism used by new and delete to acquire and release raw memory is compatible with that of malloc() and free().

  • Q:  What are the advantages of using "new" over "malloc()" ?
    Ans:  We prefer to use "new" in place of "malloc()" for memory allocation because of following reasons-

    • Constructor/Destructor - Unlike malloc(), new calls the constructor of the class. Similarly, 'delete' calls destructor of the class but free() won't.

    • Type safety - malloc() returns a void* which is not type safe as we always have to take care about its type casting else it will returns the error. But "new" returns a pointer of the right type and we need not to be worry about the type-casting.

    • Ability to Override - Being an operator, "new" can be overridden by a class, while malloc() is not overridable.




For detailed C++ Study material follow the link:- C++ Learning Series