Dynamic memory allocation in C

Default featured post

It happens sometimes you want to write a program that might need to use more memory for holding data at the run time and you cannot predict precisely how much memory you need at the programming time. For instance, in the simplest way you want to ask user to enter N numbers and then sort all numbers with one sorting algorithm (like bubble sort, quick sort, etc.). In similar situation to that you cannot predict how many numbers the user might enter, maybe 10, maybe 100 or anything else.

One simplest, basic and inefficient way is to get as much as possible memory, so you possibly will not face with any problem. In our example, you can declare an array with 32,766 or 65,535 elements. The disadvantage of this approach is that wide memory waste in the system. Although in today’s computers few more MB does not seem too crucial but imagine that you will do the same thing for 100,000,000 arrays then even the calculator might give you error for the amount of wasted memory. In other words, the wasted memory is enormous. In addition, there is possibility again that your considered memory will not be enough and then you need to change the size manually. This approach mostly means static memory allocation means that when you declare size of your memory or more specific your array you are not able to change it, at least easily.

The best solution for such situation is to use dynamic memory allocation methods which avoid any memory waste or other types of issues. In C programming language there are two ways to allocate memory dynamically. One is using linked list and the other one is utilizing malloc.h header file which is used for working with memory in heap. Each method has its own pros and cons but here I am not going to describe them. I only suggest which way is better to use in which situations.

In overall, in the situation that you need to do many adding, removing and shifting is better to use linked list since you can do all of mentioned tasks quickly and easily with changing pointers. Furthermore, for implementing graph, tree you need to use linked list.

However, when you need to save and restore data in sequence and expand, redefine and sort data, it is better to use mallac approach which is used array. In fact this approach is quite similar to ArrayList in Java or C#. For queue and stack implementation is highly recommended to use this method.

In the below part I put the sample code of each three approaches based on the example with code explanation in comment section.

First approach, static memory allocation

int MyArray[32766]; //Declare array
int i = 0;
for (i = 0; i < 32767; i++) //Loop for getting input from the user
  scanf("%d", & MyArray[i]); //Filling the elements of the array

Second method, linked list dynamic memory allocation

struct listNode { //Creating new data structure for holding user value and pointer to the next node (item)
  int data;
  struct listNode * nextPtr;
};
typedef struct listNode ListNode;
typedef ListNode * ListNodePtr;
int main(void) {
  ListNodePtr startPtr = NULL; //Creating start point of the linked list.
  ListNodePtr next = NULL; //Creating the current pointer to element or next element.
  next = malloc(sizeof(ListNode)); //Allocating memory to the element of the list.
  startPtr = next;
  for (;;) {
    scanf("%d", & next -> data); //Reading data and inserting to list.
    next -> nextptr = malloc(sizeof(next)); //Creating new element.
    next = next -> nextptr; //Move the pointer to the next element.
  }
}

Third method, malloc dynamic memory allocation

#include <malloc.h>

int main(void) {
  int j;
  int * tmp;
  int max = 10;
  int * data = malloc(max * sizeof * data); //Creating array with 10 elements by default.
  for (j = 0; j < 10; j++) //Getting data from user and insert it to the arrays.
  {
    if (j == max) //Reach to the max capacity of array
    {
      tmp = realloc(data, max + 10 * sizeof * data); //Expand the array, add 10 more elements.
      if (!tmp) //Checking for free memory availability to avoid memory leak.
      {
        printf("Memory is full cannot extend the array\n");
        exit(-1);
      } else {
        data = tmp;
        max += 10;
      }
    }
    scanf("%d", & data[j]);
  }
  free(data);
  return 0;
}

You can learn more about dynamic memory allocation from the following links.