C Language • Systems Programming

Understanding Pointers in C: Memory Addresses and Dereferencing

C
C Systems Engineering Notes • Published August 2026 • 6 min read

Pointers are often regarded as the most powerful and fundamental concept in the C programming language. Unlike many modern languages that abstract memory management behind runtime virtual machines and garbage collectors, C allows developers to interact directly with hardware memory addresses.

1. What is a Pointer?

At its core, every variable in C resides in a contiguous block of bytes within the computer's memory (RAM). Each byte possesses a distinct numeric identifier known as its memory address.

A pointer is simply a variable whose value is the memory address of another variable.

/* Basic pointer declaration and initialization */
int value = 42;
int *ptr = &value;  /* ptr now stores the memory address of value */

printf("Value of variable: %d\n", value);
printf("Address of variable: %p\n", (void *)&value);
printf("Value stored in pointer: %p\n", (void *)ptr);
printf("Value obtained by dereferencing (*ptr): %d\n", *ptr);
Key Operators:

& (Address-of operator): Extracts the memory address where a variable is stored.

* (Dereference operator): Accesses or alters the value stored at the address pointed to by the pointer.

2. Visualizing Memory Representation

When int value = 42; is declared on a 64-bit architecture, the compiler reserves 4 bytes in the stack frame. A pointer storing its address occupies 8 bytes:

Stack Memory Simulation:
0x7ffd98b0
42
int value
0x7ffd98b8
0x7ffd98b0
int *ptr
0x7ffd98c0
0x00000000
int *null_ptr

3. Pointer Arithmetic and Arrays

In C, array names act as constant pointers to their first element. When adding an integer to a pointer, the compiler multiplies the offset by the size of the underlying data type:

int numbers[3] = {10, 20, 30};
int *p = numbers;

printf("First element: %d\n", *p);       /* 10 */
printf("Second element: %d\n", *(p + 1)); /* 20 (advances sizeof(int) bytes) */
printf("Third element: %d\n", *(p + 2));  /* 30 */

4. Best Practices and Memory Safety