✦ Powered by AmygdalaAI India

Arrays in C
An Interactive Reference

From declaration to dynamic allocation — every concept visualized with animations, memory layouts, and runnable examples.

Array Concepts — The Foundation
An array is a contiguous block of memory holding elements of the same type. It is the simplest data structure and the backbone of stacks, queues, heaps, and hash tables.
What is an Array? CONCEPT

An array stores multiple values of the same type in consecutive memory locations. Each element is accessible via an index in O(1) time using pointer arithmetic.

📌 Key Properties:
• Fixed size (set at compile time for static arrays)
• All elements are the same data type
• Elements stored at contiguous memory addresses
• arr[i] ≡ *(arr + i) — index is pointer arithmetic
• First element is at index 0 (zero-indexed)
1D ARRAY — int arr[5]
Hover or click an element to inspect its address
2D ARRAY — int mat[3][4] — stored in ROW-MAJOR order
Click any cell to see its address formula
1D vs 2D Arrays COMPARISON
// 1D — linear sequence int a[5]; // 5 ints = 20 bytes // 2D — rows × columns int b[3][4]; // 3 rows, 4 cols = 48 bytes // 3D — for tensors/volumes int c[2][3][4]; // 2×3×4 = 24 ints = 96 bytes
Total bytes = rows × cols × sizeof(type)
Why Arrays Matter MOTIVATION

Arrays are the building block of almost every other data structure:

📦 Stack → array + top pointer
📦 Queue → circular array + front/rear
📦 Heap → array with parent-child formulas
📦 Hash Table → array of buckets
📦 Graph → 2D adjacency matrix
📦 String → char array + null terminator
Row-Major Order — How 2D Arrays Live in Memory KEY INSIGHT

C stores 2D arrays row by row in a single flat block of memory. This is called row-major order. Understanding this is critical for cache performance and pointer arithmetic.

2D LOGICAL VIEW → FLAT MEMORY
LOGICAL (3×3)
FLAT MEMORY (9 ints)
Address of mat[i][j] = base + (i × COLS + j) × sizeof(int)
1D Arrays — Declaration & Initialization
Learn every valid way to declare and initialize a 1D array in C, with live memory visualization for each method.
Declaration Syntax Explorer INTERACTIVE

Select a declaration style to see the syntax, memory visualization, and compiler behavior.

Uninitialized
Full Init
Partial Init
Size Inferred
Zero Init
Char Array
MEMORY CONTENT (each box = one element)
Build Your Own Array ANIMATE

Type comma-separated values to declare and visualize your array. Then access any index.

YOUR ARRAY IN MEMORY
sizeof with Arrays TRICK

Use sizeof to find array size without hardcoding the length.

int arr[] = {1,2,3,4,5}; int n = sizeof(arr) / sizeof(arr[0]); // = 20 / 4 = 5 ← number of elements for(int i=0; i<n; i++) printf("%d ", arr[i]);
⚠ sizeof only works in the same scope where the array is declared. When passed to a function, it becomes a pointer — sizeof gives 8 (pointer size), not array size!
Array as Pointer KEY CONCEPT

The array name is a constant pointer to its first element. This enables pointer arithmetic.

int arr[5] = {10,20,30,40,50}; arr // == &arr[0], address of first *arr // == arr[0] == 10 *(arr+2) // == arr[2] == 30 arr+3 // == &arr[3] (address) // These are IDENTICAL: arr[i] ≡ *(arr+i) ≡ *(i+arr) ≡ i[arr]
2D Arrays — Declaration & Initialization
2D arrays (matrices) are essential for adjacency matrices, image processing, DP tables, and more. Master every initialization form.
2D Declaration Methods INTERACTIVE
Full Init
Flat List
Partial Init
Zero Init
Identity
MATRIX VISUALIZATION
Interactive 2D Array Builder ANIMATE

Build a custom matrix by entering rows, cols, and values. Then click any cell to inspect its memory address.

MATRIX — click any cell
Row and Column Access Patterns ANIMATE

Accessing a whole row is cache-friendly (sequential). Accessing a whole column jumps by COLS elements — less efficient.

4×4 MATRIX ACCESS PATTERN
Array Assignment & Element Operations
Learn how to read, write, and traverse array elements — both 1D and 2D — with animated step-through.
1D Element Assignment Animator INTERACTIVE

Step through assignments to an array and watch memory update in real time.

int arr[8] — click Assign to write
2D Element Assignment ANIMATE

Assign values to a 3×4 matrix cell by cell. Watch the flat memory update simultaneously.

MATRIX (3×4)
FLAT MEMORY (row-major)
Loop Traversal Patterns PATTERNS

1D — forward and backward

int a[5] = {1,2,3,4,5}; // Forward for(int i=0; i<n; i++) printf("%d ", a[i]); // Backward for(int i=n-1; i>=0; i--) printf("%d ", a[i]); // Pointer style for(int* p=a; p<a+n; p++) printf("%d ", *p);

2D — nested loops

int m[3][4]; // Row-major (cache-friendly) for(int i=0; i<3; i++) for(int j=0; j<4; j++) printf("%d ", m[i][j]); // Column-major (cache-unfriendly) for(int j=0; j<4; j++) for(int i=0; i<3; i++) printf("%d ", m[i][j]);
Memory Layout Deep Dive
See exactly how the compiler lays out 1D and 2D arrays in physical memory — addresses, offsets, and pointer arithmetic explained visually.
1D Address Calculator INTERACTIVE

For a 1D array, address of element i = base + i × sizeof(type).

MEMORY LAYOUT — hover index to see address formula
2D Address Formula Visualizer ANIMATE

For a 2D array int mat[R][C], address of mat[i][j] = base + (i×C + j) × 4. Click any cell to prove it.

MATRIX (click a cell)
FLAT MEMORY STRIP
Stack vs Heap — Where Does Your Array Live? CONCEPT

Stack (static/local arrays)

void foo() { int a[5]; // ← STACK // auto-freed when foo() returns // fast allocation, fixed size // typically limited to ~8MB }
✅ Fast
✅ Auto cleanup
❌ Fixed at compile time
❌ Can't return from function

Heap (dynamic arrays)

int* a = (int*)malloc(5*sizeof(int)); // ← HEAP // manually managed with free() // size decided at runtime free(a); // must free!
✅ Size at runtime
✅ Survives function return
❌ Must call free()
❌ Slightly slower
Classic Array Programs — Animated
Step through the most common and exam-important C array programs with full animation and code walkthrough.
① Linear Search ANIMATE

Scan left to right until the target is found. Time: O(n).

ARRAY — orange=scanning, green=found
int linearSearch(int a[], int n, int target) { for (int i = 0; i < n; i++) if (a[i] == target) return i; return -1; }
② Bubble Sort ANIMATE

Repeatedly swap adjacent out-of-order elements. Time: O(n²). Watch the largest "bubble up" each pass.

BAR CHART — blue=comparing, red=swapping, green=sorted
void bubbleSort(int a[], int n) { for (int i = 0; i < n-1; i++) for (int j = 0; j < n-i-1; j++) if (a[j] > a[j+1]) { int tmp = a[j]; a[j] = a[j+1]; a[j+1] = tmp; } }
③ Find Min, Max & Sum ANIMATE
ARRAY — scanning for min/max
int findMin(int a[], int n) { int min = a[0]; for (int i=1; i<n; i++) if (a[i] < min) min = a[i]; return min; }
④ Reverse an Array ANIMATE
TWO POINTERS approach — left ↔ right
void reverse(int a[], int n) { int lo = 0, hi = n - 1; while (lo < hi) { int tmp = a[lo]; a[lo] = a[hi]; a[hi] = tmp; lo++; hi--; } }
⑤ Matrix Multiplication ANIMATE

C[i][j] = sum of A[i][k] × B[k][j] for all k. Three nested loops. Time: O(n³). Pick dimensions, randomly populate A & B, then watch C get built step by step.

A (2×2)
×
B (2×2)
=
C (2×2)
void matMul(int A[][2], int B[][2], int C[][2], int n) { for(int i=0; i<n; i++) for(int j=0; j<n; j++) { C[i][j] = 0; for(int k=0; k<n; k++) C[i][j] += A[i][k] * B[k][j]; } }
⑥ Matrix Transpose ANIMATE

Swap mat[i][j] with mat[j][i] for all i < j. Watch the matrix flip across its diagonal.

ORIGINAL
TRANSPOSED
void transpose(int m[][3], int n) { for(int i=0; i<n; i++) for(int j=i+1; j<n; j++) { int tmp = m[i][j]; m[i][j] = m[j][i]; m[j][i] = tmp; } }
Dynamic Memory Allocation — 1D Arrays
malloc/calloc/realloc let you create arrays whose size is determined at runtime. This is the foundation of dynamic data structures.
malloc — Allocate 1D Array INTERACTIVE

malloc(n * sizeof(int)) allocates n integers on the heap and returns a pointer.

STACK — pointer variable
HEAP — allocated block
int n = 5; int* arr = (int*) malloc(n * sizeof(int)); if (arr == NULL) { // ALWAYS check! fprintf(stderr, "malloc failed\n"); exit(1); } // Use like a normal array: arr[0], arr[1], ... free(arr); arr = NULL;
realloc — Resize a Dynamic Array ANIMATE

realloc grows or shrinks the allocated block. This is how dynamic arrays (like vectors) work under the hood.

DYNAMIC ARRAY — watch it grow and shrink
// Growing a dynamic array int* temp = (int*) realloc(arr, new_n * sizeof(int)); if (temp == NULL) { free(arr); exit(1); } arr = temp;
malloc vs calloc vs realloc — Full Comparison REFERENCE
// malloc — raw memory, may contain garbage int* p = (int*) malloc(5 * sizeof(int)); // p[0..4] may be any garbage values ⚠ // calloc — zero-initialized (safer for arrays) int* q = (int*) calloc(5, sizeof(int)); // q[0..4] are all 0 ✓ // realloc — resize existing block p = (int*) realloc(p, 10 * sizeof(int)); // now has space for 10 ints (first 5 preserved) // Always free when done free(p); p = NULL; free(q); q = NULL;
Dynamic Memory Allocation — 2D Arrays
Dynamically allocating 2D arrays has three common approaches: pointer-to-pointer, single malloc, and VLA. Each has trade-offs in memory layout and ease of use.
Method 1: Pointer-to-Pointer (int**) MOST COMMON

Allocate an array of row pointers, then allocate each row separately. Rows can be different lengths (jagged arrays).

POINTER-TO-POINTER MEMORY STRUCTURE
int rows = 3, cols = 4; // Step 1: allocate array of row pointers int** mat = (int**) malloc(rows * sizeof(int*)); // Step 2: allocate each row for(int i = 0; i < rows; i++) mat[i] = (int*) malloc(cols * sizeof(int)); // Use: mat[i][j] — same syntax as static! mat[1][2] = 42; // Free in reverse order! for(int i = 0; i < rows; i++) free(mat[i]); free(mat);
Method 2: Single malloc — Contiguous 2D Array EFFICIENT

Allocate one flat block and access using row×cols+col formula. Better cache performance since memory is contiguous.

ONE CONTIGUOUS BLOCK — accessed via formula
int rows=3, cols=4; // One single malloc — rows×cols elements int* mat = (int*) malloc(rows * cols * sizeof(int)); // Access: mat[i*cols + j] (manual formula) mat[1*cols + 2] = 42; // OR use C99 pointer trick for [][] syntax: int (*m)[cols] = (int(*)[cols])malloc(rows*cols*sizeof(int)); m[1][2] = 42; free(mat); // just ONE free!
Method 3: VLA — Variable Length Array (C99) C99 ONLY

C99 allows arrays whose size is a runtime variable. Allocated on the stack — no malloc/free needed, but size limited.

#include <stdio.h> void process(int rows, int cols) { int mat[rows][cols]; // ← VLA, C99 only! // size decided at runtime // lives on the STACK (no malloc/free) // ⚠ DANGEROUS for large sizes (stack overflow) mat[0][0] = 1; // automatically freed when function returns } int main() { process(3, 4); }
⚠ VLAs are optional in C11 and C23. For production code, prefer malloc for large or uncertain sizes. VLAs are fine for small temporary matrices.
Memory Layout Comparison — All 3 Methods COMPARISON
SELECT A METHOD ABOVE