solidity笔记(7)——存储区域memory storage stack——2021.5.12
solidity笔记(7)——存储区域memory storage stack一丶memory:二丶storage:三丶stack:四丶存储区域:五丶注意事项:四丶上一篇:solidity笔记(6)——modifier用法一丶memory:内存memory,用于暂存数据。其中存储的内容会在函数被调用(包括外部函数)时擦除,所以其使用开销相对较小。二丶storage:存储storage,贮存了合约声
solidity笔记(7)——存储区域memory storage stack
一丶memory:
内存memory,用于暂存数据。其中存储的内容会在函数被调用(包括外部函数)时擦除,所以其使用开销相对较小。
二丶storage:
存储storage,贮存了合约声明中所有的变量。 虚拟机会为每份合约分别划出一片独立的 存储storage 区域,并在函数相互调用时持久存在,所以其使用开销非常大。
三丶stack:
栈stack,用于存放小型的局部变量。使用几乎是免费的,但容量有限。
四丶存储区域:
不同数据类型的变量会有各自默认的存储地点:
状态变量总是会贮存在 存储storage 中
函数参数默认存放在 内存memory 中
结构、数组或映射类型的局部变量,默认会放在 存储storage 中
除结构、数组及映射类型之外的局部变量,会储存在栈中
五丶注意事项:
一个常见误区就是声明了一个局部变量,就认为它会创建在 内存memory 中,其实它会被创建在 存储storage 中:
/// 这份合约包含一处错误
pragma solidity ^0.4.0;
contract C {
uint someVariable;
uint[] data;
function f() public {
uint[] x;
x.push(2);
data = x;
}
}
局部变量 x 的数据类型是 uint[] storage,但由于 存储storage 不是动态分配的,它需要在使用前通过状态变量赋值。所以 x 本身不会被分配 存储storage 的空间,取而代之的是,它只是作为 存储storage 中已有变量的别名。
实际上会发生的是,编译器将 x 解析为一个 存储storage 指针,并默认将指针指向 存储插槽storage slot 0 。这就造成 someVariable (贮存在 存储插槽storage slot 0)会被 x.push(2) 更改。
注:在本例中,两个合约变量 someVariable 和 data 会被预先分配到两个 存储插槽storage slot 中,即 存储插槽storage slot 0 和 存储插槽storage slot 1 。上面的程序会使局部变量 x 变成指向保存了变量 someVariable 的 存储插槽storage slot 0 的指针。
/// 正确的做法
pragma solidity ^0.4.0;
contract C {
uint someVariable;
uint[] data;
function f() public {
uint[] x = data;
x.push(2);
}
}
四丶上一篇:solidity笔记(6)——modifier用法
五丶下一篇:solidity笔记(8)——pure用法
更多推荐
所有评论(0)