EVM memory
Memory is the EVM's temporary scratch space — a blank, byte-addressable array that a contract can write to and read from while it runs, and which is wiped clean the instant the call ends. It is where a contract assembles things too big for the 32-byte stack: the arguments it passes to another contract, the data it returns, and dynamic structures like arrays and strings. Think of it as a whiteboard: roomy and fast to use, but erased after every meeting.
Memory is linear and starts empty; you address it by byte offset. MSTORE writes a full 32-byte word at an offset, MSTORE8 writes a single byte, and MLOAD reads 32 bytes. Although you address individual bytes, memory grows in 32-byte words, and the EVM tracks the highest word touched. Reading or writing beyond the current size silently expands memory to cover it — there is no separate 'allocate' step.
The crucial cost wrinkle is that memory expansion is priced quadratically. The total gas to have grown memory to n words is 3*n + n²/512. For small footprints the linear 3-per-word term dominates and memory feels nearly free, but the n²/512 term means that ballooning memory to tens of thousands of words becomes punishingly expensive — a deliberate brake against a contract trying to allocate gigabytes to grief nodes.
By convention Solidity reserves the first slots of memory: bytes 0x00–0x3F are 'scratch space' for hashing, 0x40 holds the free-memory pointer (the offset where the next allocation may begin), and 0x60 is a permanently zero word. Memory is per-call and transient: a nested CALL gets its own fresh memory, and nothing in memory survives once the transaction completes. For state that must persist, a contract must use storage instead.
The quadratic term punishes very large memory allocations.
Memory clears between calls, not just transactions: if contract A calls contract B, B runs with its own empty memory and cannot see A's memory — only the calldata A explicitly passed.