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
Purpose
Pass a pointer to existing memory so the function can modify the data at that location.
2.2.Usage Pattern
Usage Pattern
2.3.When to Use
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
Memory Model
3. Double Pointer (type**)
type**)3.1.Purpose
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
Usage Pattern
3.3.When to Use
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
Memory Model
4. Why Double Pointer is Necessary
4.1.This DOESN'T work (single pointer):
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):
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
Stack Memory
Cannot return pointer to stack memory - it becomes invalid (dangling pointer).
5.2.Heap Memory
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
Single Pointer
7.2.Double Pointer
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.
- Returning pointer to stack memory
- Returning pointer to stack memory
9.2.
- Not checking allocation failure
- Not checking allocation failure
Always check:
9.3.
- Forgetting to free heap memory
- 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()






