Table of Contents

What is memory?

In the Ethereum Virtual Machine (EVM), memory is a fast, temporary workspace used during the execution of functions in smart contracts

Technically, memory is a temporary, modifiable data location. It is also byte-addressable, meaning each byte in memory has a unique address. This allows smart contracts to read from or write to specific byte positions. Memory exists for the duration of a message call (i.e., the entire execution context of a contract call) and is cleared once execution completes.

Memory in the EVM is a linear byte array. It starts empty and expands when higher memory offsets are accessed or written to, with gas charged per 32-byte word used. Smart contracts use it for intermediate computation, manipulation of dynamic data structures, and building return values.

Unlike storage (persistent and expensive) or calldata (read-only, optimized for inputs), memory is volatile. It offers flexible, mutable access to data at a moderate gas cost. It is ideal for working with dynamic arrays, structs, or strings, especially within pure, view, or temporary computation contexts.

Purpose of memory

Memory is employed when data does not need to persist. It stores data temporarily during a function’s execution and clears it once the function ends.

Uses of memory:

  • Temporary storage for loops and calculations: Data that changes during a function, such as counters or intermediate results, is held in memory.

  • Copying input arguments: Since calldata is read-only,  smart contracts must first copy values into memory to modify them.

  • Handling strings and arrays: Operations on dynamic data structures like string, bytes, or uint[] require memory for in-function modifications.

  • Returning complex data: Functions returning arrays or structs construct the output in memory before returning.

Key features of memory

Modifiable: Data can be freely modified, making it useful for algorithmic processing and building return values.

Temporary: Data only lives for the duration of a message call. It is not retained across calls or stored on-chain.

Moderate gas cost:
Because memory supports write operations and dynamic expansion, it is more expensive than calldata, but still significantly cheaper than storage.

Explicit allocation:
Developers must use the memory keyword when declaring dynamic variables like arrays, structs, or strings inside functions.

Memory use cases

Loop counters and intermediate variables: Fast and mutable for calculations.

Modifying calldata: Calldata is read-only; copy to memory first if mutation is needed.

Dynamic data structures like strings and arrays:
For in-function manipulation and return values.

Building return data:
Arrays, structs, and strings are constructed in memory before being returned to the caller of the function.

Memory vs. other data locations

In EVM Solidity smart contracts, there are four explicitly defined data locations, each with distinct purposes.

Here’s a quick comparison:

Property Memory Calldata Storage Transient storage (upcoming)
Modifiability Mutable Immutable
(read-only)
Mutable Mutable
Lifespan Temporary (during a message call) Temporary (during a message call) Persistent (on-chain) Temporary (during a transaction)
Gas cost Moderate Low High Low to moderate
Primary use In-function computation Function arguments for external calls Long-term contract state Temporary cross-functional data

Note: Transient storage (EIP-1153) has been available in the EVM since the Shanghai upgrade using inline assembly, while native Solidity support is being developed.

Memory is the go-to location when you need temporary, editable data during function execution that doesn’t need to persist when the function ends.

Solidity code example of memory 

// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;

contract MemoryExample {
    
    // Returns a modified copy of the input array
    function doubleValues(uint256[] memory input) public pure returns (uint256[] memory) {
        for (uint256 i = 0; i < input.length; i++) {
            input[i] *= 2;
        }
        return input;
    }

    // Accepts a calldata string, copies to memory, and returns modified version
    function appendHello(string calldata input) external pure returns (string memory) {
        string memory result = string(abi.encodePacked(input, " Hello"));
        return result;
    }
}

Explanation:

  • doubleValues: Accepts an array in memory and doubles each element in place before returning it.

  • appendHello: Copies a calldata string into memory, appends Hello, and returns the result.
     

Summary

Memory is a flexible, modifiable, and temporary data location in the EVM. It’s useful for efficiently handling dynamic data structures during smart contract execution. While it incurs higher gas costs than calldata, it is essential for any logic that requires mutable, in-function data.

Mastering how and when to use memory helps developers write efficient, gas-optimized, and bug-resistant smart contracts.

Related Terms

No items found.