0
pragma solidity 0.4.25;

contract A{
    struct N{
        string any;
        uint256[] numberArray;
    }

    N[] public numbers;

    function init(uint256[] _numbers) public{
        for (uint256 i = 0; i < _numbers.length; i++) {
            uint256[] memory arr;
            arr[0] = _numbers[i];
            numbers.push(N("anything", arr));
        }
    }
}

This contract compiles but throws:

transact to A.init errored: VM error: invalid opcode. invalid opcode The execution might have thrown.

What I wish to achieve

Example call:

init([1,2,3,4,5])

Outcome:

N[0] = "anything", [1]

N[1] = "anything", [2]

N[2] = "anything", [3]

N[3] = "anything", [4]

N[4] = "anything", [5]

Afterwards I would like to be able to push to the array within the array.

1

I think your problem comes from the declaration of arr arry. I think you should specify the array's length.

This following code works fine:

function init(uint256[]   _numbers) public{


   for (uint256 i = 0; i < _numbers.length; i++) {

       uint256[] memory arr=new uint256[](_numbers.length);//<===as you're using only arr[0] you can use different size (exp 1).

       arr[0]= _numbers[i];
      numbers.push(N("anything", arr));
    }
}
  • That seems to work. Can I then add a function that will push additional elements to the array? Or is it fixed size even tho it's now in storage? – Senju Oct 16 '18 at 19:57
  • you're already using only an array (arr) with a single element why do you care about size? BTW if it works consider to accept the answer. – Badr Bellaj Oct 16 '18 at 20:00
  • Yes, you answer pretty much helped to solve the problem. I tried on the function for adding more variables to the array later on. function addNumberAtIndex(uint index, uint number) public { numbers[index].numberArray.push(number); } Would be great to include it into your answer so I can accept it. – Senju Oct 24 '18 at 10:39
  • @Senju happy to hear that you can edit my answer and add your function. I request that because i don't know where addNumberAtIndex will be used – Badr Bellaj Oct 24 '18 at 10:46
  • 1
    Actually your answer fully answers the questions. Adding further numbers into the array was just my continuous approach. – Senju Oct 25 '18 at 10:46
0

I found some of the logic strange so I started breaking it down. I'm not 100% sure I solved what you want or just over-simplified it.

pragma solidity 0.4.25;

contract A{

    struct N{
        string any;
        uint[] numberArray;
    }

    N[] public numbers;

    function init(uint[] _numbers) public{
        numbers.push(N("anything", _numbers));
    }

    function getNumbersAtIndex(uint index) public view returns(uint[] _numbers) {
        return numbers[index].numberArray;
    }

}

The extra function is so you can inspect it.

At the risk of straying a little off topic, there is a risk of gas cost increase and a scaling limit. To avoid that, refactor or add functions to pass info in and get it out one element at a time.

Hope it helps.

  • Thanks for the help! I think it's over-simplified since I you are adding the whole array to one struct element. I tried to update the question to make my expectations more clear. – Senju Oct 24 '18 at 10:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.