C Programming: Pointers, Memory Management & Data Structures
Demystify how C interacts with computer hardware. Understand pointer arithmetic, stack vs. heap allocations, struct pointers, and how to write memory-safe code.
1. What is a Pointer? Addresses & Dereferencing
A pointer is simply a variable whose value is the memory address of another variable in RAM.
#include <stdio.h>
int main(void) {
int value = 42;
int *ptr = &value; // ptr stores the address of value
printf("Value: %d\n", value); // 42
printf("Address: %p\n", (void*)ptr); // e.g. 0x7ffee3b
printf("Dereferenced: %d\n", *ptr); // 42
*ptr = 100; // Modifies value directly through memory
printf("New Value: %d\n", value); // 100
return 0;
}
2. Stack vs. Heap Memory Layout
Stack memory is fast and automatically managed by function call frames. Heap memory is manually allocated at runtime and persists until explicitly freed.
// Stack allocation (freed automatically when function returns)
void stack_example(void) {
int local_array[10]; // Allocated on the call stack
}
// Heap allocation (persists across functions until free())
int *heap_example(size_t count) {
int *arr = malloc(count * sizeof(int));
if (arr == NULL) return NULL; // Always check for allocation failure
return arr;
}
3. malloc, calloc, realloc & free in Practice
Always pair dynamic allocations with free() to prevent memory leaks.
#include <stdlib.h>
int *allocate_numbers(size_t n) {
// calloc zero-initializes allocated memory
int *numbers = calloc(n, sizeof(int));
if (!numbers) return NULL;
// Resize dynamically if more space is needed
int *expanded = realloc(numbers, (n * 2) * sizeof(int));
if (!expanded) {
free(numbers); // Free original buffer if realloc fails
return NULL;
}
return expanded;
}
4. Building a Linked List in C
Linked lists are the quintessential dynamic data structure showcasing structs and pointers.
typedef struct Node {
int data;
struct Node *next;
} Node;
Node *create_node(int value) {
Node *new_node = malloc(sizeof(Node));
if (!new_node) return NULL;
new_node->data = value;
new_node->next = NULL;
return new_node;
}
void free_list(Node *head) {
Node *tmp;
while (head != NULL) {
tmp = head;
head = head->next;
free(tmp);
}
}
Frequently Asked Questions
What causes a Segmentation Fault in C?
Segmentation faults occur when a program attempts to access a memory address it does not have permission to read or write (e.g. dereferencing a NULL pointer, accessing an array out of bounds, or using memory after freeing it).
What is the difference between malloc and calloc?
malloc allocates uninitialized memory containing whatever raw bytes were previously in that location, whereas calloc initializes all allocated bytes to zero.
Want Hands-On Practice with Autograded Feedback?
Don't just read guides—practice writing code with DoxaTech's automated challenge tests. Receive real-time feedback on every Git commit.
Start Coding on DoxaTech