一些内存使用的注意事项。
uint8
或 bool
),在加载到内存中后,每个数据项都会占用完整的 32 字节空间。function breakFreeMemoryPointer(uint256[1] memory foo) external view returns (uint256) {
assembly {
mstore(0x40, 0x80) // 人为修改空闲内存指针
}
uint256[1] memory bar = [uint256(6)];
return foo[0]; // 返回 foo[0] 的值
// input [1000]
// return 6
}
假如我们传入参数 [1000],正常情况下,这个参数会被写入内存槽 0x80
,空闲内存指针此时指向 0xa0
。然而,我们将空闲内存指针强制设为 0x80
,此时内存中再装入定长数组bar
,其值 6
会被写入到 0x80
处,覆盖原有的值。因此,return foo[0]
将会返回 0x80
地址处的内容,即 6
。
uint8[] foo = [1,2,3,4,5,6];
function unpacked() external {
uint8[] memory bar = foo;
}
在这个示例中,虽然 foo
在存储槽中是紧密打包在一个槽中,但当它被读取到内存中时,数据会被解包。每个 uint8
数据类型的元素在内存中都会单独占用 32 字节空间。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!