Memory Allocation is the portion of memory reserved by the computer for use in a computer program. Variables declared are stored in the static memory during compile time which is allocated by the computer- Stack. Dynamic Memory is allocated during runtime, it's user-defined which is the Heap section. C Language offers functions that can be used to access the Heap in the header file "<stdlib.h>". The Heap is a section where all dynamically allocated memory are being stored. Pointers are used since these functions return a void pointer.
DIFFERENCES BETWEEN STACK AND HEAP
STACK | HEAP |
The stack is a region of memory that is automatically allocated during compile time when a function is called. | Heap is a region of memory that is dynamically allocated during runtime using functions like malloc() and calloc() . |
The stack is managed automatically by the compiler. | Heap is managed manually by the programmer. The programmer is responsible for allocating and freeing memory. |
The size of the stack is typically much small than the heap. It's determined during compile time. | The size of the heap can be determined during runtime. |
The lifetime of memory in the stack is short. | Memory has a longer lifespan, it is freed when no longer need with free() function. |
MALLOC() - Memory Allocation
Generally, malloc is used for structure but it can also be used for other datatypes. Malloc will initialize the data in the allocated memory to a garbage value(any value) if not initialized.
void * malloc(size_t size);
This returns a void pointer, where size is the size to be allocated in bytes
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char *ptr; //declare pointer for allocated memory
char name[] = "techWhiz"; // data to store in ptr
int i;
int len = strlen(name); // length of name in len
ptr = (char *)malloc(20); //allocating memory of 20bytes
//Looping while saving the data of name in ptr
for (i = 0; i < len; i++)
{
ptr[i] = name[i];
}
ptr[len] = '\0';//NULL terminator, ptr == name
printf("%s\n", ptr);
return (0);
}
CALLOC() - Clear Allocation
Similar to malloc() is another function calloc(), calloc() is used to dynamically allocate multiple blocks of memory and each block is of the same size initialized to 0.
void * calloc(block_size, size_t size);
//block_size is the size to be allocated in bytes
//size is the size of each individual block
REALLOC() - Reallocation
realloc() is used for resizing an already allocated memory of calloc() or malloc(). It will resize the pointer without losing the contents of the pointer except the size passed to realloc() is less than the previous size that was passed to the malloc() or calloc() function, then part of the content will be lost.
void * realloc( void *ptr; size_t new_size);
// *ptr is the aready allocated memory
// new_size is the new size for allocated memory
MEMORY LEAKS IN C
Memory leaks are caused due to the improper use of Heap. Releasing the memory to avoid memory leaks is important, this is done using the function free(). It is your responsibility to always free the memory after use. While free() tends to be useful, handling memory properly is also important for the efficiency of the program. Malloc, calloc and realloc will return NULL if the system fails to allocate memory, this issue can be solved by checking the memory status before carrying any operation on the memory. This is a better version of the previously written code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
char *_malloc_example(char *str);
int main(void)
{
char *string;
char name[] = "techWhiz"; // data to store in ptr
string = _malloc_example(name);
printf("%s\n", string); //prints the content on ptr
free(string); // This will free up the memory
return (0); // return value
}
char *_malloc_example(char *str)
{
size_t i;
int len = strlen(str); // length of name in len
char *ptr; //declare pointer for allocated memory
ptr = (char *)malloc(20); //allocating memory of 20bytes
//memory handling to avoid error
if (ptr == NULL)
return (NULL);
//Looping while saving the data of name in ptr
for (i = 0; i < len; i++)
{
ptr[i] = str[i]; //initializing ptr with values of str
}
ptr[len] = '\0'; //NULL terminator, ptr == str
return (ptr);
}
In conclusion, understanding memory allocation and properly managing memory in C is crucial for efficient and reliable programming. The stack and heap serve distinct purposes, with the stack automatically managed by the compiler and the heap manually managed by the programmer. Functions like malloc(), calloc(), and realloc() facilitate dynamic memory allocation and resizing. Additionally, it is essential to handle memory properly to prevent memory leaks, ensuring the efficient use of system resources.