Systems Programming · 14 min read

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.

terminal / code snippet
#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.

terminal / code snippet
// 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.

terminal / code snippet
#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.

terminal / code snippet
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