Pointers and Dynamic Memory in C
Understanding pointers and dynamic memory allocation is essential for mastering the C programming language. This course breaks down the fundamental ideas behind pointer dereferencing, memory…

Given `char i = 9, j = 12; char *p1, *p2; p1 = &i; p2 = &j; *p1 = *p2;`, what are the values of `i` and `j` after the assignment?
Why must a temporary pointer be used with `realloc` instead of assigning directly to the original pointer?
What does the expression `p + 1` compute when `p` is a pointer to `long int` and `&i = 1230`?
In the function `void incrementer(int *x) { *x = *x + 1; }`, what is the value of `a` after calling `incrementer(&a);` if `a` was initially 5?
What is the primary difference between `malloc` and `calloc` when allocating memory for an array of integers?
After executing `free(p); p = NULL;`, what is the state of pointer `p`?
Why is it unsafe to call `free(p); *p = 10;` after freeing memory?
When passing an array to a function as `void afficher(int t[], int n)`, how does the function receive the array?
What is the correct way to access the `reel` field of a structure through a pointer `p`?
Pointers and Dynamic Memory in C: Core Concepts
Understanding pointers and dynamic memory allocation is essential for mastering the C programming language. This course breaks down the fundamental ideas behind pointer dereferencing, memory management functions (malloc, calloc, realloc, and free), and common pitfalls such as dangling pointers. Each section is designed to be SEO‑friendly, using clear headings, keyword‑rich paragraphs, and structured lists to help learners and search engines alike.
1. Pointer Dereferencing and Assignment
When a pointer p holds the address of a variable x, the expression *p refers to the value stored at that address. Assigning to *p directly modifies the original variable.
- Key point:
*p = 20;changesxto20becauseppoints tox. - Common mistake: Assuming the assignment creates a temporary copy; it does not.
Example:
int x = 5;
int *p = &x; // p now holds the address of x
*p = 20; // x becomes 20
2. Copying Values Through Pointers
When two pointers reference distinct variables, dereferencing one and assigning it to the other copies the value, not the address.
- Given
char i = 9, j = 12;andchar *p1 = &i, *p2 = &j;, the statement*p1 = *p2;copies the value ofjintoi. - Result:
ibecomes12whilejremains12.
Visual representation:
i (9) <-- p1 --> address of i
j (12) <-- p2 --> address of j
*p1 = *p2 // i now holds 12
3. Safe Use of realloc
The realloc function attempts to resize an existing memory block. If it fails, it returns NULL and leaves the original block untouched. Assigning the result directly to the original pointer can cause loss of the original address, leading to memory leaks.
- Best practice: Use a temporary pointer.
int *temp = realloc(original, newSize); if (temp) { original = temp; // safe replacement } else { // handle allocation failure, original is still valid } - This pattern ensures that if
reallocfails, you still have a valid pointer to free.
4. Pointer Arithmetic
Pointer arithmetic respects the size of the pointed‑to type. Adding 1 to a pointer advances it by sizeof(type) bytes.
- For a
long intpointerpwhere&i = 1230(assumingsizeof(long int) = 4), the expressionp + 1yields the address1234. - Remember: the actual numeric result depends on the system’s data model (e.g., 8‑byte
longon 64‑bit platforms).
5. Passing Pointers to Functions
Functions can modify variables indirectly by receiving a pointer to the variable.
- Example function:
void incrementer(int *x) { *x = *x + 1; } - Calling
incrementer(&a);whenais initially5results inabecoming6.
6. malloc vs. calloc
Both functions allocate raw memory, but they differ in initialization:
mallocallocates the requested number of bytes without initializing them. The memory contains indeterminate (garbage) values.callocallocates memory for an array and automatically zero‑initializes every byte.- Typical usage:
int *arr1 = malloc(10 * sizeof(int)); // values undefined int *arr2 = calloc(10, sizeof(int)); // all elements are 0
7. Freeing Memory and Nullifying Pointers
After releasing a memory block with free, the pointer still holds the old address, which is now invalid. Setting the pointer to NULL prevents accidental dereferencing.
- Correct pattern:
free(p); p = NULL; // p is now a null pointer, safe to test before use - A null pointer is guaranteed not to point to any valid object, making subsequent checks reliable.
8. Dangling Pointers and Undefined Behavior
Dereferencing a pointer after its memory has been freed leads to undefined behavior because the pointer becomes dangling.
- Example of unsafe code:
free(p); *p = 10; // undefined behavior – p is dangling - Always ensure a pointer is either set to
NULLor reassigned before further use.
9. Summary of Key Takeaways
- Dereferencing a pointer (
*p) accesses the value at the address stored inp. - Pointer arithmetic adds multiples of the pointed‑to type’s size.
- Use a temporary pointer with
reallocto avoid memory leaks. mallocleaves memory uninitialized;calloczero‑initializes it.- Always
freeallocated memory and set the pointer toNULLto prevent dangling pointers. - Passing pointers to functions enables direct modification of variables.
By mastering these concepts, you will write safer, more efficient C programs and avoid common memory‑related bugs that can cause crashes or security vulnerabilities.
