5.1.14C Programming

Dynamic memory — malloc, calloc, realloc, free

2,414 words11 min readdifficulty · medium5 backlinks

WHAT: The four functions

All declared in <stdlib.h>. They deal in bytes and hand you a void * (a generic address you cast to the type you want).


WHY each exists (the 80/20 distinctions)


HOW: Deriving the correct call from first principles

You never memorize "malloc takes a number." You derive the argument:

Figure — Dynamic memory — malloc, calloc, realloc, free

Common mistakes (Steel-manned)


Active Recall

Recall What does

free actually free? It returns the block to the heap allocator's free list for reuse — it does not wipe the bytes and does not change your pointer variable.

Recall Why prefer

malloc(n * sizeof(*p)) over malloc(n * sizeof(int))? sizeof(*p) automatically tracks p's type, so the line stays correct if the type changes — less bug surface.

Recall Give one case where

calloc is strictly better than malloc. When you need zero-initialized memory (counters/flags); on most implementations it also splits the size into count/size and detects multiplication overflow (though that overflow check is implementation-defined, not standard-mandated).


Recall Feynman: explain to a 12-year-old

Imagine a library. A normal array is like booking a fixed table before you arrive — you must guess how many friends are coming. The heap is the librarian: you walk up and say "I need 5 chairs" right now (malloc). If a chair was left messy you clean it yourself; if you ask the tidy librarian (calloc) they hand you clean chairs. Need more chairs later? realloc finds a bigger spot and carries your stuff over. When you leave, you must return the chairs (free) or nobody else can use them — that's a "leak." And once returned, stop sitting on them (don't use the pointer), or you'll get a stranger's lap!


Connections

  • Pointers in C — dynamic memory returns pointers; you must understand void * and casting.
  • Arrays vs Pointersa[i] works on malloc'd blocks because of pointer arithmetic.
  • The Stack and the Heap — where automatic vs dynamic variables live and why lifetimes differ.
  • Memory Leaks and Valgrind — tooling to catch missing frees.
  • sizeof operator — the basis of computing byte counts.
  • Undefined Behavior in C — use-after-free, double-free, out-of-bounds.

What header declares malloc/calloc/realloc/free?
<stdlib.h>
What is the contents of memory returned by malloc?
Uninitialized garbage (not zeroed)
What is the contents of memory returned by calloc?
All bytes set to zero
What do the two arguments of calloc(count, size) mean?
number of elements and size of each; it allocates count*size bytes
Does the C standard guarantee calloc detects multiplication overflow?
No — overflow handling is implementation-defined; most real libcs check and return NULL, but it is not standard-mandated
What does malloc return on failure?
NULL
What does realloc preserve?
The contents of the old block (up to the smaller of old/new size)
Why use a temporary pointer with realloc?
On failure it returns NULL but keeps the old block; assigning directly would leak the old block
What is a dangling pointer?
A pointer that still holds the address of memory that has already been freed
What should you do immediately after free(p)?
Set p = NULL; to avoid use-after-free and double-free
What is a memory leak?
Allocated heap memory that is never freed and whose pointer is lost, so it can't be reused
Why double capacity when growing a buffer?
Geometric growth gives amortized O(n) total insertion cost instead of O(n^2)
What is the type of pointer malloc returns?
void *, implicitly convertible to any object pointer type in C
Is free(NULL) safe?
Yes, it is a defined no-op
How many bytes does malloc(n * sizeof(*p)) request for n elements?
n × sizeof(*p) bytes

Concept Map

motivates

managed by

reserve uninitialized

reserve zeroed

resize block

return block

bytes from

does multiply and

may detect

preserves

then set

check

Runtime size unknown

Heap memory

stdlib.h functions

malloc n bytes

calloc count size

realloc ptr n

free ptr

n times sizeof deref p

Zero-filled memory

Overflow check impl-defined

Old contents

ptr equals NULL

NULL on failure

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, normal array jaise int a[100]; mein tumhe pehle se size pata hona chahiye — yeh "compile time" pe fix ho jaata hai. Lekin real programs mein size aksar runtime pe decide hota hai (user kitna data dega, pata nahi). Iska solution hai dynamic memory: tum OS se heap naam ki jagah se memory maangte ho exactly jitni chahiye. Yeh kaam karte hain chaar functions — malloc, calloc, realloc, free — sab <stdlib.h> mein.

Simple farak yaad rakho: malloc memory deta hai par andar garbage hota hai (clean karna tumhara kaam). calloc wahi karta hai par sab zero se bhar deta hai, aur count aur size ko alag-alag lekar khud multiply karta hai. Ek baat dhyan rakho — log kehte hain "calloc overflow-safe hai," par C standard yeh guarantee nahi karta; zyada-tar real libc (glibc, musl) overflow detect karke NULL de dete hain, par yeh implementation-defined hai, standard ka rule nahi. realloc purane block ko bada/chhota karta hai aur purana data copy karke preserve rakhta hai. free memory ko wapas heap ko de deta hai taaki dusra koi use kar sake.

Sabse important rule: jitne malloc/calloc kiye, utne free karo — warna memory leak ho jaata hai (memory waste, kabhi wapas nahi milti). Aur free(p) ke turant baad p = NULL; likho, warna pointer "dangling" ho jaata hai aur use karna = crash ya silent bug (use-after-free). realloc ke saath hamesha temporary pointer use karo: tmp = realloc(v, ...), fail hone par v safe rehta hai, success pe v = tmp; — direct v = realloc(v,...) likhoge to fail hone par purana block leak ho jaata hai.

Ek aur pro tip: buffer grow karte time capacity double karo (2,4,8,...), ek-ek karke mat badhao — isse total copying ka cost amortized O(n) ho jaata hai, O(n²) nahi. Yeh exam aur interview dono mein poocha jaata hai.

Go deeper — visual, from zero

Test yourself — C Programming

Connections