Skip to content
ByteStepStart with recursion

Arrays: why the index is free

Free, no account

An array is one block of memory holding values of the same size, one after another with nothing in between. Everything arrays are good at and everything they are bad at comes from that one sentence.

Below is the same array drawn twice: the row of slots a programmer thinks in, and the addressed block the machine actually has. They are the same thing. The slot numbered 3 is not a label stuck on a value, it is a position in the block.

Press play on read. No searching happens, at any index. Then try insert and drag the index from one end to the other, and watch the price change.

1function read(a, i) {
2 const size = 4 // bytes per element
3 const at = a.base + i * size // where it is
4
5 return memory[at] // go there, once
6}

The array

fixed slots, and the values sitting in them

Reading index 5

  1. 31
  2. 14
  3. 58
  4. 62
  5. 9
  6. 27
  7. 41
  8. 75

8 elements

The same block, addressed

what the machine has: one run of bytes

Block · 32 byteslow address
  1. 0x7FFD0100[0]31
  2. 0x7FFD0104[1]14
  3. 0x7FFD0108[2]58
  4. 0x7FFD010C[3]62
  5. 0x7FFD0110[4]9
  6. 0x7FFD0114[5]27
  7. 0x7FFD0118[6]41
  8. 0x7FFD011C[7]75
0x7FFD0120 · limit8 of 8 slots

Eight numbers in one block, each 4 bytes, one after another. Nothing here will be searched for.

1/4
Detail
4 steps

The sum that makes reading free, the same property making insertion expensive, and why counting starts at zero.

The sum that makes it free

To find element 5, the machine does not look at elements 0 to 4. It works out where element 5 is:

address = start + index × size

One multiplication, one addition, then go there. The same two operations for the first element and for the millionth, which is what random access means: any position costs what any other position costs, and the word random is about arbitrary rather than unpredictable.

That sum needs two things to be true. Every element must be the same size, or multiplying by the index is meaningless. And they must be contiguous, with no gaps, or the count of elements stops matching the distance in bytes. Take either away and there is nothing left but searching.

The same property, sending the bill

Now switch to insert at index 0. To put a value at the front, every other element has to move up one slot first: 7 of them. Insert at the very end instead and 0 elements move.

The array cannot simply leave a gap and remember it, because a gap breaks the arithmetic above. Shifting is what keeps the block unbroken, and keeping the block unbroken is the only reason reading was free. It is one property, billed twice.

Removing is the same in reverse: take an element out of the middle and everything after it moves down to close the hole. Drag the index while watching the count and the shape comes out immediately. It is a straight line, worst at the front, free at the back.

Why counting starts at zero

The first element is at start + 0 × size, which is the start. The index is not a position in a queue, it is the distance from the beginning, measured in elements. Counting from one would put a subtraction in the middle of the most common operation in computing.

Know someone stuck on this? Send it to them.

A classmate, a study group, someone learning this on their own at midnight. The link opens the lesson set up exactly as you have it, the same function and the same number, and runs from the first step so they watch the whole thing build rather than landing in the middle of it.

Before this one

Memory, addresses and pointers

Addresses have to mean something before a sum over them can. Start there if a box holding another box\u2019s number is new.

Start there →