15 Common mistakes with memory allocation, you should avoid

15 Common mistakes with memory allocation, you should avoid

In C language, memory is allocated at runtime using the memory management functions (calloc, malloc … etc.). The memory management functions are guaranteed that if the memory is allocated, it would be suitably aligned to any object which has the fundamental alignment. The fundamental alignment is less than or equal to the largest alignment that’s supported by the implementation without an alignment specification.

The dynamic memory allocation resolves a lot of problems that are faced by the developer during the development. One of the bad features of the dynamic memory allocation is that it is not destroyed by itself either compiler. It is only destroyed by the developer to call the free function explicitly, sometimes it becomes the roots of the problems. You can see my another article, problems with dynamic memory allocation.

In this article, I will discuss 15 common mistakes with memory allocation that are generally done by the developers. If you are fresher and you have no basic idea of the dynamic memory allocation then it is my advice read about the memory management functions before reading this article.

Forget to check return value of malloc

It is a very common mistake and can be the cause of the segmentation fault. When we call the malloc (memory management function) then it returns the pointer to allocated memory. If there is no free space is available, the malloc function returns the NULL. It is good habits to verify the allocated memory because it can be NULL. You already know that if we try to dereference the null pointer, we will get the segmentation fault.

Let’s see the example code,
In below code, everything is fine until the malloc function doesn’t return the null pointer. If malloc returns the NULL, the code will crash.

We can resolve the above problem to verify the return value of malloc function. If malloc returns the null pointer, the code will display an error message and terminate the execution.

Initialization errors

Generally, c programmer uses malloc to allocate the block of memory. Some programmers assume that malloc allocated memory is initialized by the zero and they use the block of memory without any initialization. In some scenario, it does not reflect the bad effect but sometimes it creates hidden issues.

Let’s see the example code,
In below code, programmer incorrectly assumes that value of the allocated memory is zero and performs some arithmetical operation.

Note: If you have required initialized memory, use the memset() along with malloc or called the calloc() that allocate the initialized memory.

Access the already freed memory

When you freed the allocated memory then still pointer pointing to the same address. if you attempt to read or write the freed pointer then might be you succeed but it is illegal and can be the cause of the code crashing. It is also a reason to born the dangling pointer.

Freeing the same memory multiple times

A free function is used to deallocate the allocated memory. If piData (arguments of free) is pointing to a memory that has been deallocated (using the free or realloc function), the behavior of free function would be undefined.

The freeing the memory twice is more dangerous then memory leak, so it is very good habits to assigned the NULL to the deallocated pointer because the free function does not perform anything with the null pointer.

Freeing memory that was not allocated

The free function only deallocates the allocated memory. If piData is not pointing to a memory that is allocated by the memory management function, the behavior of the free function will be undefined.

Let’s see the example code,
In below code, I am getting the segmentation fault because I am trying to deallocate the auto variable memory using the free function.

Forget to free the allocated memory

The dynamically allocated memory only destroy by the programmer to calling the free function explicitly. If the programmer forgets to deallocate the allocated memory, then the allocated memory is not available to another process and it is reserved for the entire life of the program. It is the one of the important cause of the memory leaks. The memory leak is a common and dangerous problem and type of resource leak.

Note: once you allocate a memory than allocated memory does not allocate to another program or process until it gets free.

Using malloc () in the wrong place

Declaration of the normal array is easy and fast.The allocated memory of the normal array is automatically released by the compiler when the control comes out from the function. In the other hand, dynamic memory allocation is slow and only released by the developer explicitly to call the free function. So it is beneficial to use the normal array when the array is not needed after the function returns.

Note: This technique is supported by the C99 or C11  compilers.

Let’s see the example code,
In below code, I am describing the place where is the normal array is better than the dynamic array. See the article, how to create the 1D and 2D array in c. 

Calculating the size of the dynamic array using the sizeof operator

Some developers use the sizeof operator to calculate the size of the dynamically allocated array.The sizeof operator is used to calculate the size of the static array, not used for dynamic array. If you tried to calculate the size of the dynamic array then you will get the size of the pointer.

Output: 8 bytes (64-bit machine)

So It is a great idea to carry the length of the dynamic array. Whenever you have required the length of the array, you need to read the stored length. To implement this idea in the program we need to allocate some extra space to store the length. It is my advice, whenever you use the technique then check that length of the array should not exceed the type of the array.

For example,
Suppose you need to create an integer array whose size is n. So to carry the array length of the array, you need to allocate the memory for n+1

int *piArray = malloc ( sizeof(int) * (n+1) );

If memory is allocated successfully, assign n (size of the array) its 0 places.

piArray[0] = n;
* piArray = n;

Now it’s time to create a copy of original pointer but to left one location from the beginning.

int * pTmpArray = piArray +1;

Note: if you are new, see this article arithmetic operation on the pointer.

Now, whenever in a program you ever required the size of the array then you can get from copy pointer.

ArraySize = pTmpArray[-1];

After using the allocated memory don’t forget to deallocate the allocated memory.

free (piArray);

Improper use of the memory management function

It is very important to use the memory management function in proper ways. Some developer uses the zero size malloc in their program. It is very dangerous because if the size of the requested space is zero, the behavior will be implementation-defined. The return value of the malloc could be a null pointer or it shows the behavior like that size is some nonzero value.

In below program, I am using the zero size malloc. The output of the zero size malloc is implementation defined, so it will be dangerous to use the returned value of the malloc.

Output: Implementation-dependent

Does not counting the number of allocated memory

It is good habits to count the number of allocated memory in the program, this method prevents the memory leak and freed the memory multiple times.

In this technique, we will create two global counters and initialize them with 0. In every successful allocation, we will increment the value of the counter1 (Allocate_Counter ) and after the deallocating the memory we will increment the counter2 (Deallocate_Counter). In the end of the application, the value of both counters should be equal.

This method helps you to track the status of allocated memory. To implement this technique we need to create three customize function, one for memory allocation and second for memory deallocation and last one to check the memory leak.

Accessing a dynamic array out of boundaries

It is a common mistake that is done by the developers. When you access the dynamic array out of the boundary then the behavior of your program can be undefined. We can resolve this problem to put a check condition before to access the array.

Let see an example code,

Working on the original pointer

It can be a reason for the undefined behavior, it creates a problem when there is accidental change occurred on the pointers.To prevents undefined behavior it is a good habit to work on a copy of the pointer, it preserves the address of allocating memory.If there is any accidental change occurred on the pointer, this technique helps you to get the actual address of allocating memory that is needed at the time of memory deallocation.

Re-assignment of pointer

Sometimes reassignment of the pointer creates the problems.If you do not use the dynamically allocated memory properly (in the situation of shallow copy), it can cause of the code crashing or unwanted result.

In above example, piData1 and piData2 are two pointers. I am allocating the memory to piData1 using the malloc and assigned 100 to the allocated memory.

If I will assign the allocated memory to the pointer piData2, the allocated memory is shared by both pointers.

shared memory

When you will free the memory that is pointed by the piData1 than you will get an undefined result for accessing of piData2.

deallocate memory

Dereferencing a pointer without allocating some memory

When you will try to access a pointer without giving a proper memory, you will get the undefined result. Many new developers access the pointers without allocating a memory and frustrated with coming results. A pointer with not valid memory is called dangling pointers, for more deep knowledge you can read this article, dangling void null wild pointers.

Let see the below code,

Proper comments on the program

I think it is good habits to write the comment in every section of the code. It always reminds you that what you did. It helps you if you read your code after some months or years.

You can see this article, 10 interview question on dynamic memory allocation.

One comment

  1. You should not refer to a block of memory you have malloc’d as a dynamic array. It is not an array. Also I don’t think C has dynamic or static arrays as you’ve implied. There are compile-time sized arrays and variable length arrays (VLAs). The former can be static or externally scoped. The latter cannot. You can use sizeof on either of these two types of arrays. However, VLAs sizes are computed at run-time unlike all other uses of sizeof.

Leave a Reply