1. Core Concept: Pass-by-Value
Everything in C is passed by value - all parameters are copied when passed to functions.
2. Single Pointer (type*)
type*)2.1. Purpose
Pass a pointer to existing memory so the function can modify the data at that location.
2.2. Usage Pattern
2.3. When to Use
- Caller allocates memory (stack or heap)
- Small, fixed-size data structures
- Short lifetime (function-local scope is fine)
- Performance critical (stack allocation is faster)
- Initializing or modifying existing data
- Examples: configuration structs, temporary buffers
2.4. Memory Model
3. Double Pointer (type**)
type**)3.1. Purpose
Pass the address of a pointer variable so the function can allocate new memory and update the caller's pointer to point to it.
3.2. Usage Pattern
3.3. When to Use
- Function allocates memory (on heap)
- Size unknown until runtime
- Data needs to outlive the function call
- Large data structures (avoid stack overflow)
- Building dynamic data structures (linked lists, trees)
- Examples: reading files, database queries, parsing unknown-size data
3.4. Memory Model
4. Why Double Pointer is Necessary
4.1. This DOESN'T work (single pointer):
The pointer headerOut is passed by value (copied). Assigning to it only changes the local copy.
4.2. This WORKS (double pointer):
By passing &myHeader, we give the function access to modify the original pointer variable.
5. Stack vs Heap Memory
5.1. Stack Memory
Cannot return pointer to stack memory - it becomes invalid (dangling pointer).
5.2. Heap Memory
Local pointer variable is on stack (destroyed when function returns), but the data it points to is on heap (persists).
6. Comparison Table
| Aspect | Single Pointer | Double Pointer |
|---|---|---|
| Who allocates | Caller | Function |
| Parameter type | type* param | type** param |
| Caller passes | &variable | &pointer |
| Function modifies | Data content | Pointer itself |
| Memory location | Stack or heap (caller decides) | Heap (function allocates) |
| Cleanup | Automatic (if stack) | Manual free() required |
| Use case | Initialize existing data | Create and return new data |
7. Complete Examples
7.1. Single Pointer
7.2. Double Pointer
8. Memory Analogy
Think of pointers like addresses written on paper:
-
Single pointer: "Here's the address of a house, go paint it red"
- The house already exists
-
We are just modifying it
-
Double pointer: "Here's a piece of paper where an address will be written, I'll build a new house and write its address there"
- The house doesn't exist yet
-
Function builds it and tells us where it is
9. Common Pitfalls
9.1. 1. Returning pointer to stack memory
9.2. 2. Not checking allocation failure
Always check:
9.3. 3. Forgetting to free heap memory
10. Key Takeaways
-
C only has pass-by-value - everything is copied
-
Single pointer - to modify existing memory
-
Double pointer - to allocate new memory and return it
-
Choose based on who allocates the memory
-
Stack memory is automatic but temporary
-
Heap memory persists but requires manual cleanup with
free()











