内存布局

Solidity 保留四个 32 字节的槽,使用特定的字节范围(包括端点)如下

  • 0x00 - 0x3f (64 字节): 用于哈希方法的暂存空间

  • 0x40 - 0x5f (32 字节): 当前分配的内存大小(也称为。空闲内存指针)

  • 0x60 - 0x7f (32 字节): 零槽

暂存空间可以在语句之间使用(即在内联汇编中)。 零槽用作动态内存数组的初始值,永远不要写入(空闲内存指针最初指向 0x80)。

Solidity 始终将新对象放置在空闲内存指针处,并且内存永远不会被释放(这在将来可能会改变)。

Solidity 中内存数组中的元素始终占用 32 字节的倍数(即使对于 bytes1[] 也是如此,但对于 bytesstring 则不是)。 多维内存数组是指向内存数组的指针。 动态数组的长度存储在数组的第一个槽中,然后是数组元素。

警告

Solidity 中有一些操作需要大于 64 字节的临时内存区域,因此无法容纳在暂存空间中。 它们将被放置在空闲内存指向的位置,但鉴于它们的生命周期很短,指针不会更新。 内存可能被清零,也可能不被清零。 因此,不应期望空闲内存指向已清零的内存。

虽然使用 msize 来获得一个肯定清零的内存区域似乎是一个好主意,但在没有更新空闲内存指针的情况下非临时地使用这样的指针可能会产生意想不到的结果。

与存储中布局的差异

如上所述,内存中的布局与 存储 中的布局不同。 下面是一些示例。

数组差异示例

以下数组在存储中占用 32 字节(1 个槽),但在内存中占用 128 字节(4 个元素,每个元素 32 字节)。

uint8[4] a;

结构布局差异示例

以下结构在存储中占用 96 字节(3 个 32 字节的槽),但在内存中占用 128 字节(4 个元素,每个元素 32 字节)。

struct S {
    uint a;
    uint b;
    uint8 c;
    uint8 d;
}