2.24 EVM Memory
Remember that the EVM is a stack based architecture. It has calldata, the volatile memory and the non-volatile storage.
EVM memory has a linear layout, which means that all the memory locations are stored linearly next to each other, and memory locations can be addressed at byte level. The EVM instructions that are used to access memory are MLOAD
/MSTORE
that operate on the word size (256 bits) and, if one wants to store a single byte from the stack to memory, one can use the MSTORE8
. All locations in memory are zero initialized.
Reserved Memory and the Free Memory Pointer
The first two 32 byte slots (from 0x0
to 0x40
) are reserved by Solidity
as a scratch space for the hashing methods.
The third slot (again 32 bytes; from 0x40
to 0x60
) is used for the free memory pointer, so this points to the next byte of memory within Solidity
that is considered as "free" or in effect this also indicates the amount of allocated memory currently within Solidity
.
The fourth slot (32 bytes; from 0x60
to 0x80
) is referred to as a zero slot and is used by Solidity
as an initial value for dynamic memory arrays. We'll talk about that shortly.
Therefore, it makes sense that the initial value of the free memory pointer and Solidity
is 0x80
(the fifth slot) because the first four 32 byte slots are reserved by Solidity
. The free memory pointer effectively points to memory that is allocatable in the context of Solidity
at any point in time and whenever memory is allocated by the compiler, it updates the free memory pointer.
These concepts should be familiar, if you have looked at memory allocation of any other programming languages, these just happen to be the specific ways in which Solidity
handles memory allocation using the familiar concept of the free memory pointer.
Memory Layout
Solidity
places new memory objects at the free memory pointer and all this memory that is allocated is never freed or deallocated. All these concepts related to memory layout matter from a security perspective only: if the developer is manipulating this memory directly in the assembly language support provided by Solidity
because, if one is using Solidity
as a high-level language without using assembly, then all this is automatically handled by the Solidity
compiler itself.
Memory Arrays
For memory, every element within arrays in Solidity
occupy 32 bytes. This is something we mentioned in the context of the byte array and how every element occupying 32 bytes wastes a lot of space. Despite the type of the memory array, this is not true for bytes
and string
types.
For multi-dimensional memory arrays, those are pointers to memory arrays.
For dynamic arrays, it is very similar to the storage even within memory: these are stored by maintaining the length of the dynamic array in the first slot of that array in memory followed by the array elements themselves.
Zeroed Memory
With respect to zeroed memory (memory containing zero bytes), there are no guarantees made by the Solidity
compiler that the memory being allocated has not been used before, so one can't assume that the memory contents contain zero bytes.
The reason for this is that there is no built-in mechanism to automatically release or free allocated memory in Solidity
. As you can imagine, this has a security impact because if one is using memory allocated objects, those are not guaranteed to be zeroed memory. Then the default values may not be zeros. These again are relevant only if memory is being manipulated directly in assembly within Solidity
. This should not be much of a concern if one is not using assembly.
Last updated