Mastering C Memory Management: malloc, realloc, memset, memcpy & More
This article explains how C programs allocate, resize, initialize, and transfer memory using functions like malloc, free, realloc, memset, memcpy, memmove, and alloca, and provides coding standards to avoid out‑of‑bounds errors, leaks, and use‑after‑free bugs.
Theory Section
Linux Implementation Principles – Virtual Memory Technology
Linux Implementation Principles – Large Page Memory
Heap Memory Operations
malloc() / free() Memory Allocation and Release
malloc() requests virtual memory space.
If the requested size is less than 128 KB, malloc() uses brk() to allocate from the Heap Segment.
If the requested size exceeds 128 KB, malloc() uses mmap() to allocate from the MMAP Segment.
Function prototype: void *malloc(size_t size); Parameter size : the number of bytes to allocate, usually obtained with sizeof().
Return value:
On success, a pointer to the allocated block (type void*).
On failure, NULL.
Memory allocation and release must be paired and each block freed only once to avoid leaks.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char name[100];
char *description;
strcpy(name, "Zara Ali");
/* Allocate memory for 200 characters */
description = (char *)malloc(200 * sizeof(char));
if (description == NULL) {
fprintf(stderr, "Error - unable to allocate required memory
");
} else {
strcpy(description, "Zara ali a DPS student in class 10th");
}
printf("Name = %s
", name);
printf("Description: %s
", description);
/* Release memory */
free(description);
return 0;
}Running output:
$ ./main
Name = Zara Ali
Description: Zara ali a DPS student in class 10threalloc() Memory Resizing
realloc() changes the size of an allocated heap block.
If enough contiguous free space exists, the block is expanded in place.
Otherwise a new larger block is allocated, data is copied, and the old block is freed.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char name[100];
char *description;
strcpy(name, "Zara Ali");
description = (char *)malloc(200 * sizeof(char));
if (description == NULL) {
fprintf(stderr, "Error - unable to allocate required memory
");
} else {
strcpy(description, "Zara ali a DPS student in class 10th
");
}
/* Resize to 100 characters */
description = (char *)realloc(description, 100 * sizeof(char));
if (description == NULL) {
fprintf(stderr, "Error - unable to allocate required memory
");
} else {
strcat(description, "She is in class 10th
");
}
printf("Name = %s
", name);
printf("Description: %s
", description);
free(description);
return 0;
}Running output:
$ ./main
Name = Zara Ali
Description: Zara ali a DPS student in class 10th
She is in class 10thmemset() Memory Initialization
Initializing memory prevents garbage data. Since malloc() does not zero memory, memset() is often used.
Prototype:
#include <string.h>
void *memset(void *s, int c, unsigned long n);s : pointer to the memory area.
c : value to set (commonly 0).
n : number of bytes to set.
Example:
#include <stdio.h>
#include <string.h>
int main(void) {
int i;
char str[10];
char *p = str;
memset(str, 0, sizeof(str)); // correct: use sizeof(str)
for (i = 0; i < 10; ++i) {
printf("%d ", str[i]);
}
printf("
");
return 0;
}memcpy() / memmove() Data Transfer
Both copy memory blocks; memmove() safely handles overlapping regions.
Prototypes:
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);Parameters:
dest : destination address.
src : source address.
n : number of bytes to copy.
memcpy example:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "hello world";
char dest[20];
printf("Before memcpy:
");
printf("src: %s
", src);
printf("dest: %s
", dest);
memcpy(dest, src, strlen(src) + 1);
printf("After memcpy:
");
printf("src: %s
", src);
printf("dest: %s
", dest);
return 0;
}memmove example:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "hello world";
char str2[] = "xxxxxxxxxx";
printf("Before memmove:
");
printf("str1: %s
", str1);
printf("str2: %s
", str2);
memmove(str2, str1, strlen(str1) + 1); // handles overlap
printf("After memmove:
");
printf("str1: %s
", str1);
printf("str2: %s
", str2);
return 0;
}Stack Memory Operations
alloca() Memory Allocation
Heap allocation is unordered and can cause fragmentation; using stack memory where appropriate reduces this overhead. alloca() allocates temporary memory on the stack and does not require explicit free.
Memory Operation Coding Standards
Prohibit Out‑of‑Bounds Access
Prefer sizeof and strlen to compute lengths instead of manual calculations.
When using memcpy or memset, ensure the length does not exceed the target buffer.
Consider pointer type size when performing ++ or -- on pointers.
Prohibit Memory Leaks
All resources allocated within a function must be released before the function returns.
Be careful with macros that contain return or break; ensure resources are freed beforehand.
When cleaning up structure pointer members, free from the deepest level upward.
When cleaning pointer arrays or queues, also free from the deepest level upward.
Avoid allocating the same memory block multiple times.
Prohibit Use After Free
Set pointers to NULL after freeing; always check for NULL before use.
When modules with strong coupling call each other, carefully manage call relationships to prevent use of deleted objects.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
