Pointers and dynamic memory allocation notes — Unit 4
Free unit-wise study notes on pointers and dynamic memory allocation for Programming for Problem Solving in C, Semester 1 of B.Tech — Computer Science & Engineering — key concepts, examples, important questions and a revision checklist for semester exams.
Twenty hand-written sheets covering the most feared topic in C: Pointers. Breaks down pointer arithmetic, array-pointer duality, and dynamic memory (malloc/calloc) using clear memory diagrams to prevent segmentation faults.
Notebook — 20 pages
Page 1
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
1. What is a Pointer?
When you declare `int x = 5;`, the computer finds a random empty locker in RAM (say, locker number 2048), puts the number 5 inside it, and labels the locker 'x'.
A Pointer is just a variable that holds a LOCKER NUMBER (a memory address) instead of normal data.
Normal Variable
`int x = 5;` Stores data (5).
Pointer Variable
`int *p = &x;` Stores an address (2048).
Page 2
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
2. The Two Magic Operators (& and *)
Pointers rely entirely on two operators. Mastering them is 90% of the battle.
1. `&` (Address-Of Operator): Returns the memory address of a variable.
2. `*` (Dereference Operator): Goes to the address stored in a pointer, and grabs the value inside it.
Dry Run
int x = 10; // x is 10. Assume x is at address 5000.
int *p = &x; // p now stores the number 5000.
printf("%d", x); // Prints 10 (Direct access)
printf("%d", &x); // Prints 5000
printf("%d", p); // Prints 5000
printf("%d", *p); // Goes to 5000, grabs the value. Prints 10.
Page 3
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
3. Reading Declarations Backwards
C declarations can get messy. The secret trick to reading any C declaration is to read it backwards (right-to-left).
Examples
`int *p;`
p -> is a pointer (*) -> to an integer (int).
`int p;`
p -> is a pointer () -> to a pointer () -> to an integer (int).
`const int *p;`
p -> is a pointer (*) -> to an integer (int) -> that is constant (const).
We will use this trick heavily when dealing with double pointers and arrays of pointers later.
Page 4
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
4. Pointer Arithmetic
You can add and subtract numbers from pointers, but it does NOT work like normal math. Pointer math is automatically scaled by the `sizeof` the data type it points to.
Assume integer takes 4 bytes. Address of p is 1000.
int *p = 1000;
p = p + 1;
// What is p now? It is NOT 1001!
1.1. The compiler sees `p + 1`.
2.2. It checks what p points to: an `int`.
3.3. It finds `sizeof(int)` = 4 bytes.
4.4. The actual math it performs is: 1000 + (1 * 4) = 1004.
Page 5
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
5. Pointer Math Rules
There are strict rules about what mathematical operations are legal on memory addresses.
LEGAL Operations
1. Adding/subtracting an integer to a pointer (p+1, p-3).
2. Subtracting two pointers of the SAME type (p2 - p1). This tells you how many elements are between them.
ILLEGAL Operations (Compile Error)
1. Adding two pointers together (p1 + p2).
2. Multiplying or dividing pointers.
3. Adding a float to a pointer.
Why is `p1 + p2` illegal? Because adding two random memory addresses (like 1000 + 4000 = 5000) gives you a completely meaningless, random location in RAM.
Page 6
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
6. Array-Pointer Duality
In C, arrays and pointers are almost the exact same thing. The compiler treats the name of an array as a constant pointer to its first element.
int arr[3] = {10, 20, 30};
// 'arr' is a constant pointer pointing to the '10'.
1.Because `arr` is a pointer, `arr + 1` points to the next integer (the 20).
2.If we want the value, we dereference it: `*(arr + 1)`.
3.This is literally what the square bracket syntax does behind the scenes!
A Funny Consequence
Because arr[i] means *(arr + i)
And addition is commutative *(i + arr)
You can legally write `i[arr]` instead of `arr[i]`. It compiles perfectly.
Page 7
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
7. Dry Run: Array Traversal
Predict the output of the following pointer traversal.
1.1. `*p` prints the value at the current address (10).
2.2. `*(p+1)` looks one slot ahead and prints it (20), but `p` ITSELF did not move.
3.3. `*p++` is tricky. The postfix `++` happens AFTER the expression. So it prints the current value (10), and THEN moves the pointer `p` forward by one slot.
4.4. `*p`. The pointer moved in the last step, so it now points to 20. Prints 20.
Page 8
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
8. Pointers and Strings
A string in C is just an array of characters, ending with a null terminator `\ `. Therefore, a string can be manipulated using a `char *`.
Array Declaration
`char str[] = "Hello";` Creates an editable array in the Stack. You can change `str[0] = 'M'`.
Pointer Declaration
`char *str = "Hello";` Points to a read-only string in the Data Segment. Trying to change `str[0]` causes a crash (Segfault).
Printing with Pointers
char *p = "Code";
while(*p != '\ ') {
printf("%c", *p);
p++; // Move to next character
}
Page 9
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
9. Dynamic Memory Allocation
Normally, you must declare array sizes as constants: `int arr[100];`. If you only end up needing 5 slots, you wasted 95. If you need 105, your program crashes. This is 'Static Memory Allocation' (allocated on the Stack at compile time).
⇒The Solution: The Heap
Dynamic Memory Allocation (DMA) allows you to ask the Operating System for memory DURING runtime. This memory comes from a massive pool called the 'Heap'.
`malloc()`: Memory Allocate
`calloc()`: Contiguous Allocate
`realloc()`: Re-allocate
`free()`: Free memory
Page 10
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
10. malloc()
`malloc` takes one argument: the TOTAL number of bytes you want. It finds a block of that size on the Heap, and returns a `void *` (a generic pointer) to the start of it.
// I want an array of 'n' integers.
int n = 5;
int *arr;
// 5 integers * 4 bytes each = 20 bytes total.
arr = (int *)malloc(n * sizeof(int));
1.Why the `(int )`? Because malloc returns a generic `void `. We must 'Typecast' it to tell the compiler: 'Treat this block as a sequence of integers.'
2.Why `sizeof(int)`? Never hardcode '4'. Some old systems use 2 bytes for int. `sizeof` makes your code portable.
Page 11
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
11. calloc()
`calloc` does the exact same job as `malloc`, but with two key differences.
1. It takes TWO arguments: the number of items, and the size of one item.
2. It automatically initializes every single byte to ZERO (clears the garbage).
// I want an array of 5 integers, all set to 0.
int *arr;
arr = (int *)calloc(5, sizeof(int));
malloc vs calloc
`malloc` is slightly faster because it skips the clearing step.
`calloc` is safer if you need to ensure the array starts clean.
Page 12
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
12. Checking for Failure (NULL)
What if you ask for 50 Gigabytes of RAM, and the computer doesn't have it? The Operating System will deny the request. `malloc` and `calloc` will return a `NULL` pointer (address 0).
The Safe Way to Allocate
int *arr = (int *)malloc(100 * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
exit(1); // Abort program
}
// If we get here, it's safe to use 'arr'.
Page 13
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
13. free() and Memory Leaks
Local variables on the Stack are automatically destroyed when a function ends. Heap memory is completely manual. It survives until the program ends, OR until you explicitly tell the OS you are done with it using `free()`.
int *arr = (int *)malloc(100 * sizeof(int));
// ... use the array ...
free(arr); // Give the memory back to the OS!
Memory Leaks
If you write a loop that calls `malloc` but never calls `free`, your program will slowly eat up all the RAM in the computer until it crashes the whole system. This is called a Memory Leak.
Page 14
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
14. realloc()
You used `malloc` for 5 integers. Suddenly, you realize you need 10 integers. You can't just expand an array normally, but you can use `realloc` to resize a Heap block.
int *arr = (int *)malloc(5 * sizeof(int));
// Need more space!
arr = (int *)realloc(arr, 10 * sizeof(int));
1.How realloc works behind the scenes:
2.1. It tries to just extend the current block if there is empty space next to it.
3.2. If there is NO space, it finds a brand new block of size 10.
4.3. It secretly COPIES your old data into the new block.
5.4. It frees the old block automatically.
6.5. It returns the new pointer address.
Page 15
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
15. Double Pointers (Pointer to Pointer)
A pointer stores the address of a variable. But a pointer is ALSO a variable itself, meaning it has its own memory address! You can create a pointer that stores the address of another pointer. This is a Double Pointer (``).
int x = 10; // x is at address 1000
int *p = &x; // p holds 1000. p itself is at address 2000.
int **q = &p; // q holds 2000.
1.Dereferencing trace:
2.q => gives 2000 (address of p)
3.*q => goes to 2000, grabs value => 1000 (address of x)
4.q => goes to 2000, grabs 1000, goes to 1000, grabs value => 10
Double pointers are heavily used in C when you want to pass a 2D array to a function, or when you want a function to modify a pointer itself.
Page 16
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
16. Dangling Pointers
A Dangling Pointer is a pointer that points to a memory location that has been deleted or given back to the OS. It's like having a key to a house that was demolished.
How it happens
int *p = (int *)malloc(sizeof(int));
*p = 5;
free(p); // Memory is returned to OS.
// At this exact moment, 'p' is Dangling!
*p = 10; // SEGFAULT! Writing to deleted memory.
Page 17
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
17. Void Pointers
A `void ` is a generic pointer. It can store the address of ANY data type (int, float, char). `malloc` returns a `void ` because it doesn't know what you plan to store in the memory.
int x = 10;
float y = 5.5;
void *p;
p = &x; // Valid
p = &y; // Also valid!
Page 18
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
18. Array of Pointers
You can create an array where every single slot holds a pointer. This is extremely useful for storing lists of strings without wasting space.
2D Array vs Array of Pointers
// A standard 2D array forces all rows to be the same width:
char names[3][10] = {"Bob", "Alice", "Christopher"};
// 'Bob' wastes 7 bytes of empty padding.
// An Array of Pointers:
char *names[3] = {"Bob", "Alice", "Christopher"};
// This just creates 3 pointers. Each pointer points to exactly
// the required memory in the Data Segment. Zero wasted padding!
Page 19
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
19. Function Pointers
Just like variables, Functions live in memory (in the Code Segment). Therefore, functions have memory addresses! You can create a pointer to a function and call it through the pointer.
int add(int a, int b) { return a + b; }
int main() {
// Declare a pointer 'ptr' to a function that takes two ints and returns int
int (*ptr)(int, int) = &add;
// Call the function via the pointer
int result = ptr(5, 10);
}
This is an advanced feature used in operating systems and game engines to create 'Callback' functions (passing a function as an argument to another function).
Page 20
Wink Notes
B.Tech CSE — 1st Semester
Programming for Problem Solving in C
— Unit - 4 —
20. Quick Revision Checklist
⇒Unit 4 Mastery
Do you understand why `*p++` increments the pointer and not the value?
Can you explain why `arr[i]` and `*(arr + i)` are identical?
Do you know the exact differences between `malloc` (garbage) and `calloc` (zeros)?
Can you write the code to safely allocate memory and check for `NULL`?
Do you know the difference between a Memory Leak and a Dangling Pointer?