Arrays
Can be fixed or dynamic sized at compile-time
T[k] -> fixed size of type T, with k elements
T[] -> dynamic size of type T
T[][5] -> 5 dynamic-sized arrays of T (read in reversed)
Storage arrays
Can be fixed or dynamic.
For fixed:
size must be specified during declaration.
Once declared, the array size cannot be changed.
Any attempt to reference beyond the last array position will result in an error.
For dynamic:
size of the array is not mentioned during the declaration.
size of the dynamic array can be changed during the runtime as elements are added/removed.
Methods
length
delete
push/pop (only for dynamic)
In a fixed-size array, we can not insert a new element as it increases the length of an array. To insert a new element in the dynamic size array we use the push method; this increases the length.
Init arrays
Fixed arrays:
all elements initialize to 0 -> fixedArr1[1] = 0
can partially assign, as seen in
initializeFixedArr2()
. fixedArr2 = [6,0,0]length is 3, as elements are initialized to default values.
Dynamic arrays:
have not defined number of elements.
therefore no elements or default values exist.
cannot call dynArr[0]. will revert.
default length of 0.
must init w/ values first.
When calling
get
ondynArr
it will revert, as no assignment has been done.Can call
length
on an unassigned array, it will return 0.
Push and Pop
dynArr
being initialized but unassigned.call
push()
: this assigns 3 elements to it. its length is now 3.dynArr[2]
: returns 13call pop(): removes last element, 13. length is now 2.
dynArr[2]: will revert. there is no element there anymore.
dynArr[1]: returns 12
Delete
call push() -> dynArr = [11, 12, 13]
delete dynArr[1] -> dynArr = [11, 0, 13]
length remains 3
push/pop modify length
delete does not modify length
Removing a specific element
Remove array element by shifting elements from right to left
Copy all the elements forward, starting from the specified index. Pop the last element as its repeated.
Remove array element by copying last element into to the place to remove
Deleting an element creates a gap in the array.
One trick to keep the array compact is to move the last element into the place to delete.
Memory Arrays
Only fixed-size memory array. Dynamic array cannot be created in memory. No push/pop
available
new
keyword is used to initialise arrays in memory.
Bad example
you can compile this, but calling test() will revert.
you could remove the assignment and the function will no longer revert - but obviously this achieves nothing.
Assignments from memory
to memory
only create references.
memory
to memory
only create references.y
,z
andzz
are all arrays in memoryChanges to one
memory
variable affect all others referencing the same data.
Layout in storage
Dynamic arrays
Storage slot of a dynamic array stores the length of the array; and updates it accordingly.
Dynamic array elements are stored elsewhere.
Why: compiler has no way of knowing how many elements there would be; cos dynamic, so it cannot store the elements consecutively starting from the storage slot at which the dynamic array is declared. Danger of clashing into the next storage slot which could hold some other state variable.
Location of array elements
hash(slot) = location of the first array element, and the rest follow
Nested dynamic arrays
s points to another array, s[0]
s[0] points to the series of elements, s[0] = [4,0,6]
s[1] pointer would be stored beside s[0], and so forth
storage layout of dynamic nested arrays: https://www.youtube.com/watch?v=Zi4BANKFNP8
Storage pointers and Data Location Effects
myArray is not a separate unique array that is created from x.
its a pointer to the location in storage where coders resides.
modifying values through the storage pointer will affect both myArray and x.
Assignments between
storage
andmemory
(or fromcalldata
) always create an independent copysee: uint[] memory memArray = x;
Assignments from
storage
to a localstorage
variable also only assign a referencesee: uint[] storage myArray = x;
Assignments to storage
always copy, even if sourcing from reference variables
storage
always copy, even if sourcing from reference variablesDangling references to storage array elements
add(): Create a dynamic array with a single nested dynamic array uint256[][] s, such that s[0] = [4,0,6]
fuckAround(): create a storage pointer to the last element in s, which is a pointer to s[0]; since there is only 1 element.
pop s[0]
push some hex value into the same storage location
Last updated