Diseño en memoria
Solidity reserva cuatro ranuras de 32 bytes, con rangos de bytes específicos (incluidos los extremos) que se utilizan de la siguiente manera:
0x00
-0x3f
(64 bytes): espacio de desecho para métodos hash0x40
-0x5f
(32 bytes): tamaño de memoria asignado actualmente (aka. puntero de memoria libre)0x60
-0x7f
(32 bytes): ranura cero
El espacio de desecho se puede utilizar entre instrucciones (es decir, dentro de un assembly en línea). La ranura cero se utiliza como valor inicial para matrices de memoria dinámica y nunca debe escribirse en (el puntero de memoria libre apunta inicialmente a ``0x80`”).
Solidity siempre coloca nuevos objetos en el puntero de memoria libre y la memoria nunca se libera (esto podría cambiar en el futuro).
Los elementos en matrices de memoria en Solidity siempre ocupan múltiplos de 32 bytes (esto
es incluso cierto para bytes1[]
, pero no para bytes
y string
).
Las matrices de memoria multidimensionales son punteros a matrices de memoria. La longitud de
una matriz dinámica se almacena en la primera ranura de la matriz y seguida de los elementos
de la matriz.
Advertencia
Hay algunas operaciones en Solidity que necesitan un área de memoria temporal superior a 64 bytes y, por lo tanto, no cabe en el espacio de desecho. Se colocarán donde apunta la memoria libre, pero dado su corta duración, el puntero no se actualiza. Es posible que la memoria se ponga a cero o no. Debido a esto, uno no debería esperar que la memoria libre apunte a cero.
Aunque puede parecer una idea buena usar msize
para llegar a un área
de memoria puesta a cero definitivamente, el uso de tal puntero no-temporalmente
sin actualizar el puntero de memoria libre puede tener resultados inesperados.
Diferencias con el diseño en el almacenamiento
Como se describió anteriormente, el diseño en la memoria es diferente del diseño en storage. A continuación hay algunos ejemplos.
Ejemplo de diferencia en matrices
La siguiente matriz ocupa 32 bytes (1 ranura) en almacenamiento, pero 128 bytes (4 elementos con 32 bytes cada uno) en memoria.
uint8[4] a;
Ejemplo de diferencia en el diseño de estructura
La siguiente estructura ocupa 96 bytes (3 ranuras de 32 bytes) en almacenamiento, pero 128 bytes (4 elementos con 32 bytes cada uno) en memoria.
struct S {
uint a;
uint b;
uint8 c;
uint8 d;
}