MEMORY MANAGEMENT

This refers to how a system or a programmer handles the allocation and deallocation of memory for data storage. Unlike languages like Java or Python, C is not a memory-managed language, so the system does not automatically handle dynamic memory for you, instead, the programmer must explicitly manage it.

All data in C must be located in one of three places, that is;

  • The Stack (Automatic Storage) → This is used for local variables and unction arguments.

  • The Data Segment (Static Storage) → Used for global variables, constants and literals.

  • The Heap (Allocated Storage) → Used for dynamic memory allocation, where the size of the data may not be known at runtime.

For Dynamic Memory Allocation and managing memory on the Heap, C uses standard library functions that are defined in <stdlib.h>. These functions return a void pointer (void*), which simply records a memory location without an associated type.

malloc(size_t size)
//requests a block of memory of a specific size. The initia values of the memory are indeterminate

calloc(size_t nmemb, size_t size)
//Allocates memory for an array of n elements, each of a specific size and initializes all bits to zero

realloc(void *pntr, size_t size)
//Changes the size of a previously allocated memory block. It deallocates the old object and returns a pointer to a new ine, preserving the original contents up to  the lesser of the new and old sizes.

free(void *pntr)
//Returns the allocated memory back to the operating sysytem. If null, no action occurs. Attempting to free memory that was not dynamically allocated results in undefined behaviour. 

For Good Practice:

  • Every malloc call needs exactly one free

  • Never use a pointer after freeing it, set it to NULL afterward as a safety habit

  • Never free a pointer twice

  • Always check the return value of malloc

  • Never return a pointer to a local variable