Pointers & Dynamic Memory
10h
Class hours
7
Topics
0%
0/7 done
Why This Unit Matters
Master C's most powerful and dangerous feature: direct memory access via pointers. Learn pointer arithmetic, how pointers relate to arrays and strings, and how to allocate memory dynamically at runtime.
Pointer Basics
A pointer is a variable that stores the memory address of another variable. Every variable in a C program lives at some address in RAM — a pointer lets you hold that address and work through it.
- —Declaration: int *p; — p is a pointer to int. The asterisk (*) means "pointer to".
- —& operator (address-of): p = &x; — p now holds the address of variable x.
- —* operator (dereference): *p — reads the value at the address p holds.
- —NULL pointer: int *p = NULL; — safe initialization; always check before use.
- —void pointer: void *p; — generic pointer, can hold any address, must cast before dereference.
- —sizeof(pointer) = 8 bytes on 64-bit systems (4 bytes on 32-bit) — regardless of the type pointed to.
Declare a pointer, read and modify a variable through it.
"How will you define pointer? Write a program that illustrates how a pointer variable can change the value of a normal variable." — asked multiple years. Know both & and * thoroughly.
Pointer Arithmetic
You can perform arithmetic on pointers — but movement is measured in units of the pointed-to type, not in raw bytes. This is why pointer arithmetic is safe for traversing arrays.
- —p++ — moves pointer forward by sizeof(*p) bytes (4 bytes for int*, 1 byte for char*).
- —p-- — moves pointer backward by sizeof(*p) bytes.
- —p + n — address n elements ahead (not n bytes).
- —p2 - p1 — distance between two pointers in elements (not bytes).
- —Comparison: p1 < p2, p1 == p2 — valid when both point into the same array.
- —You cannot multiply or divide pointers — only add/subtract integers, or subtract two pointers.
Use p++ to step through each element and print its address.
Pointer arithmetic is scale-aware: an int pointer jumping by 1 advances 4 bytes on most systems. This makes it ideal for array traversal — know this distinction for short-answer questions.
Pointers & Arrays
In C, the name of an array is a constant pointer to its first element. This equivalence means array subscript notation and pointer arithmetic are interchangeable.
- —arr is equivalent to &arr[0] — a pointer to the first element.
- —arr[i] is exactly the same as *(arr + i) — the compiler translates one to the other.
- —You can assign a pointer to an array: int *p = arr; — then use p[i] or *(p+i).
- —Strings are char arrays; a char* can traverse them character by character until '\0'.
- —Difference: arr itself is a constant pointer — you cannot do arr++ (use a separate pointer variable).
Demonstrates that arr[i] and *(arr+i) are identical.
"Write a program to find the sum/maximum of an array using pointers." — extremely common. Show the *(arr+i) notation explicitly; examiners want to see you know the equivalence.
Pointers & Functions
Passing a pointer to a function lets that function modify the caller's variable directly — this is call by pointer (a form of call by reference). Pointers to structures also unlock the arrow operator.
- —Call by pointer: void swap(int *a, int *b) — dereference inside to change originals.
- —Pointer to struct: struct Student *p = &s; — access members with p->name (arrow operator).
- —p->member is shorthand for (*p).member — identical behavior, cleaner syntax.
- —Returning a pointer from a function: int* getMax(...) — never return address of a local variable (dangling!).
- —Arrays passed to functions are always pointers — the function receives the array address.
Pass a struct by pointer and modify it inside a function using the -> operator.
"Explain null pointer and void pointer. Write a program using pointer to store and display student data (roll, name, marks)." — know the arrow operator p->member vs (*p).member distinction.
Dynamic Memory Allocation
Static arrays require the size at compile time. Dynamic Memory Allocation (DMA) lets you request memory from the heap at runtime, making programs flexible. All DMA functions live in <stdlib.h>.
| Function | Syntax | Initializes? | Use case |
|---|---|---|---|
| malloc | malloc(n) | No (garbage) | Single block of n bytes |
| calloc | calloc(count, size) | Yes (zero) | Array of count elements |
| realloc | realloc(ptr, newSize) | Partial | Resize existing allocation |
| free | free(ptr) | — | Release heap memory |
- —malloc returns void* — always cast: int *arr = (int*)malloc(n * sizeof(int));
- —Always check: if (arr == NULL) { printf("Allocation failed"); return 1; }
- —free(ptr) releases memory back to the heap — must be called exactly once per allocation.
- —After free, set ptr = NULL to prevent accidental reuse (dangling pointer).
- —Heap memory persists until explicitly freed — unlike stack (automatic) variables.
Allocate an integer array at runtime, read values, compute sum and average, then free.
"Why use DMA instead of a fixed-size array? Explain malloc() and calloc() with example." — asked every year. Know: malloc does NOT zero-initialize, calloc does. Always cast and always free.
Memory Safety
Pointer misuse causes the most notorious bugs in C: crashes, data corruption, and security vulnerabilities. Understanding these categories is essential for exams and real code.
Dangling Pointer
Points to freed/out-of-scope memory. Fix: set to NULL after free.
Wild Pointer
Declared but never initialized. Fix: always initialize at declaration.
NULL Pointer
Points to address 0 — dereferencing crashes. Fix: always check != NULL.
Memory Leak
Allocated but never freed. Fix: every malloc needs a matching free.
- —Never dereference a NULL pointer — always guard with if (p != NULL).
- —Never dereference a wild pointer — always initialize: int *p = NULL; or int *p = &x;
- —Never access memory after free() — set pointer to NULL immediately after freeing.
- —Never free the same pointer twice — double-free causes undefined behavior.
- —Every malloc/calloc/realloc must have exactly one matching free — no more, no less.
Shows safe patterns: set to NULL after free, check before dereference.
"Differentiate: dangling pointer, wild pointer, and NULL pointer." — these three are a frequent short-answer question. Give the definition, cause, and fix for each.
Practice & Quiz
Active Recall Questions
Try to answer each question from memory before revealing the answer. This is the most effective study technique for long-term retention.
What is a pointer? How is it declared and initialized?
What is pointer arithmetic? What operations are valid?
What is the difference between malloc() and calloc()?
What is a NULL pointer? What is a dangling pointer?
How are arrays and pointers related in C?
Exam-Style Questions
These questions match the style and marks distribution of TU BCA past papers. Attempt each question before revealing the full solution.
Write a C program using DMA to read n integers, find their sum and average. Free memory when done.
5 marksWhat is a void pointer? Write a C program demonstrating void pointer usage.
5 marksWrite a C program using pointers to swap two numbers (call by reference). Explain why this works when call by value doesn't.
5 marksHow to Remember
How to Remember Unit 5
Pointers are the most confusing topic in C. These mnemonics and visual anchors cut through the confusion with concrete mental models.
Mnemonics
Star is overloaded
"Declaration * = pointer type, Expression * = value"
int *p; — here * means "p is a pointer to int" (declaration context)
*p = 5; — here * means "the value at the address p holds" (expression context)
The star is overloaded — context determines meaning. Always ask: am I declaring or using?
DMA functions — MCRF
My Computer Runs Fast
M — Malloc: allocates raw bytes, garbage values, no zero-fill
C — Calloc: allocates and Clears to zero (safe for arrays)
R — Realloc: Resizes an existing allocation
F — Free: releases the memory back to the heap
Memory Tricks
& gives Address, * gives Value
& = "and-dress" (address). Think: & looks like a label tag pinned to a variable. * = "x marks the spot" — the treasure (value) buried at that address.
Pointer arithmetic is type-aware
When you do p+1, C adds sizeof(*p) bytes — not 1 byte. An int pointer jumps 4 bytes, a char pointer jumps 1 byte, a double pointer jumps 8 bytes.
Always check malloc return
malloc returns NULL if the system is out of memory. Never skip the NULL check — dereferencing NULL crashes the program immediately.
free() then NULL — always both
After calling free(p), set p = NULL immediately. This prevents use-after-free bugs where the pointer still holds the old (now invalid) address.
Memory leak mental image
Not calling free() is like leaving a tap running in an empty house — the water (memory) flows away and never returns until the program exits. The OS reclaims it then, but during the run it is gone.
Unit 5 — Before the Exam Checklist