Arrays in C Programming (1D, 2D & Memory Layout)

An array in C is a contiguous sequence of elements belonging to the exact same data type. Because all elements sit side-by-side in physical memory, the CPU can access any element in O(1) constant time through direct address arithmetic. Understanding memory layout and pointer decay is vital to working with C arrays safely.
1. Contiguous Memory Layout and 1D Array Declaration
When you declare int arr[5], the compiler reserves a contiguous block of 20 bytes (5 elements * 4 bytes each) on the stack. C uses zero-based indexing, where the first element is at arr[0] and the final element is at arr[4].
2. The O(1) Base Address Formula
How does C locate arr[i] instantly? The compiler computes the physical address using the base address formula: Address(arr[i]) = Base_Address + (i * sizeof(DataType)) Because this involves a single multiplication and addition, element lookup takes deterministic constant time regardless of array size.
int numbers[4] = {10, 20, 30, 40};
// &numbers[2] == (char*)numbers + (2 * sizeof(int))
printf("Index 2 value: %d\n", *(numbers + 2)); // Prints 303. 2D Arrays and Row-Major Memory Ordering
While 2D arrays are conceptually grids with rows and columns, physical computer RAM is strictly one-dimensional. C stores multi-dimensional arrays in Row-Major Order: all elements of Row 0 are placed first, followed immediately by Row 1, Row 2, and so forth.
4. Array Decay into Pointers and Bounds Protection
In most C expressions, the name of an array decays into a constant pointer to its first element (arr == &arr[0]). Crucially, C never checks array bounds at runtime. Accessing arr[10] on a 5-element array results in buffer overflow and undefined behavior.
Runnable C example
#include <stdio.h>
int main(void) {
int scores[5] = {70, 85, 90, 65, 100};
int grid[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
int n = sizeof(scores) / sizeof(scores[0]);
int sum = 0;
for (int i = 0; i < n; i++) {
sum += scores[i];
}
printf("Elements: %d\n", n);
printf("Sum: %d\n", sum);
printf("Average: %.1f\n", (double)sum / n);
printf("2D array:\n");
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 3; c++) {
printf("%d ", grid[r][c]);
}
printf("\n");
}
return 0;
}
Expected Output
Elements: 5
Sum: 410
Average: 82.0
2D array:
1 2 3
4 5 6
Frequently Asked Questions
What is the relationship between arrays and pointers in C?
An array name evaluates to the address of its first element. Writing arr[i] is syntactically identical to *(arr + i). However, unlike pointers, array base addresses cannot be reassigned.
Why does passing an array to a function lose its size information?
When passed to a function, arrays decay into a pointer to the first element. The sizeof() operator inside the function returns the pointer size (8 bytes on 64-bit systems) rather than the array capacity. You must always pass the array length as a separate argument.