You need to use an array in storage because it is not possible to resize memory arrays.
contract D {
uint[] myArray;
function Test() constant returns (uint[]) {
myArray.push(123);
return myArray;
}
}
Otherwise you need to define the size of the array during initialization:
contract C {
function f(uint len) {
uint[] memory a = new uint[](7);
bytes memory b = new bytes(len);
// Here we have a.length == 7 and b.length == len
a[6] = 8;
}
}
There is no need to initialize storage
arrays in Solidity. Only memory
arrays has to be initialized before usage.
So in your case, no need to initialize x
inside Bar
as long as you are not assigning a value to one of the x
indexes inside your foobar
. Actually, making initialization in your code will consume gas for no reason.
The following code works well for your case:
function foobar(address a) public {
Bar memory b;
b.owner = a;
//When 'b' is pushed to 'bars' array:
// (1) 'b' will be converted from memory to storage.
// (2) And 'x' inside it will be initialized automatically.
bars.push(b);
}
However, if you need to access x and push some value you can use push
:
function foobar2(address a, uint x0) public {
Bar memory b;
b.owner = a;
bars.push(b);
//Trying: b.x[0] = x0; will generate error. Since, b.x is a memory array that is not initialized!
bars[bars.length - 1].x.push(x0); //This will work fine!
}
Actually, you can still initialize your memory array, as an empty one, as follow:
function foobar3(address a) public {
Bar memory b = Bar(a, new uint[](0)); //Thanks to "James Duffy" for his answer.
bars.push(b);
}
Last thing to mention is that: If you have multi values, that you need to insert to your x
array, then you can do this as follow:
function foobar4(address a, uint[] _x) public {
Bar memory b = Bar(a, _x);
bars.push(b);
}
Or as follow. But, this will consume more gas:
function foobar5(address a, uint[] _x) public {
Bar memory b;
b.owner = a;
bars.push(b);
Bar storage c = bars[bars.length - 1]; // Get the newly added instance of the storage struct
for (uint i = 0; i < _x.length; i++) {
c.x.push(_x[i]);
}
Check full code at the nice EthFiddler: https://ethfiddle.com/fQI6Khgz3E
Best Answer
Is perfectly normal as
uint256[] storage _ownerAmount;
is not initialized, meaning that it defaults to slot 0 possibly overwriting whatever is already occupying that slot.However, looking at your code you probably don't need a dynamic storage array. Only dynamic storage arrays can be resized (pushed to / popped from), this makes sense when the number of elements in unknown, but that is not your case due to :
A more gas efficient implementation could rely only on static memory arrays with fixed size, such as :