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
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 elementsfor(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
FLAT MEMORY VIEW (row-major)
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.
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)
voidfoo() {
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 runtimefree(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
intlinearSearch(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
voidbubbleSort(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
intfindMin(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
voidreverse(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.
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 pointersint** mat = (int**) malloc(rows * sizeof(int*));
// Step 2: allocate each rowfor(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 elementsint* 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>voidprocess(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
}
intmain() {
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