pvdocs /Data Structure/Arrays

Arrays

A contiguous space in memory that holds a list of multiple elements, all stored sequentially.


How Memory Works

When you create an array, the computer reserves a block of memory where each element sits right next to the others. Think of it like a row of boxes:

[11 | 11 | 00 | 00 | 11 | 11 | 00 | 00]

Each cell is a byte. An i32 (32-bit integer) takes 4 bytes, so 2 integers occupy 8 bytes total.


Typed Arrays (Low Level)

At the lowest level, an array is just raw bytes in memory — an ArrayBuffer. How you interpret those bytes depends on the type you use.

// javascript
const a = new ArrayBuffer(8) // 8 bytes of memory, all zeros

const a32 = new Uint32Array(a) // views those 8 bytes as 2 x 32-bit integers
// Uint32Array(2) [ 0, 0 ]

const a8 = new Uint8Array(a)   // views those 8 bytes as 8 x 8-bit integers
// Uint8Array(8) [ 0, 0, 0, 0, 0, 0, 0, 0 ]

Both a32 and a8 point to the same memory. Changing one changes the other:

a32[0] = 4294967295  // 0xFFFFFFFF in hex

// a32 → Uint32Array(2) [ 4294967295, 0 ]
// a8  → Uint8Array(8)  [ 255, 255, 255, 255, 0, 0, 0, 0 ]
// a   → ArrayBuffer { [Uint8Contents]: <ff ff ff ff 00 00 00 00> }

4294967295 in binary is 32 ones (11111111 11111111 11111111 11111111), which is 255 in each of the 4 bytes.


Static Arrays (Fixed Size)

In languages like Rust, arrays have a fixed size defined at creation time:

let my_array: [i32; 4] = [1, 2, 3, 4]
//                  ^ size is fixed at 4

Memory layout (each i32 = 4 bytes = 32 bits):

[11 11 11 | 11 11 11 | 11 11 11 | 00 00 00]
   [0]         [1]         [2]       [3]

Reading — O(1) (Constant Time)

Accessing any element by index is instant, no matter the size of the array:

my_array[0]  // Big O: O(1)

The computer calculates the exact memory address: start + (index × byte_size). No searching needed.

Adding Beyond the Limit — O(n) (Linear Time)

Static arrays cannot grow. If you try my_array[4] = 123, it fails because there is no 5th slot — other data may already occupy that memory.

[11 | 11 | 11 | 00]  ← your array ends here
                   [XXXXX]  ← memory already taken by something else

The only solution is to create a new, larger array and copy everything over:

let new_array: [i32; 5] = [1, 2, 3, 4, 123]

This is O(n) because you must copy all n existing elements into the new location.


Dynamic Arrays (JavaScript)

JavaScript arrays are not typed or fixed-size — they are actually objects under the hood:

const arr = [10, 20, 30]

// Internally treated as:
const arr = {
  "0": 10,
  "1": 20,
  "2": 30,
  length: 3
}

This means JavaScript arrays can hold mixed types:

const arr = [1, 2, "banana", [1, 2, 3]]

JavaScript runtimes implement this differently under the hood: - Node.js → backed by C++ - Bun → backed by Zig


Big O Summary

Operation Big O Why
Read by index O(1) Direct memory address calculation
Write by index (within bounds) O(1) Direct memory address calculation
Add element (static, out of bounds) O(n) Must copy all elements to new memory

Key Takeaways