4

I'm trying to work with 2D in-memory arrays in Solidity, in which the size is not known at compile time. I've noticed that if I define the array size as a constant, then I can use this syntax, which compiles and returns the expected 10x10 array:

uint256 constant size = 10;

function initArray() public view {
    uint256[size][size] memory arr;
    // ...
}

However, if I define the size using a variable, I get problems:

uint256 size = 10;

function initArray() public view {
    uint256[size][size] memory arr;
    // ...
}

Which leads to: TypeError: Invalid array length, expected integer literal or constant expression.

So I then try to use the new syntax, but I can't figure out how to use it for 2D arrays. First I try the simplest thing:

uint256 size = 10;

function initArray() public view {
    uint256[][] memory arr = new uint256[][](size)(size);
    // ...
}

This leads to an error: TypeError: Type is not callable, which makes sense. But then, how do I define the size of the inner arrays? I then tried:

uint256 size = 10;

function initArray() public view {
    uint256[][] memory arr = new uint256[][](size);
    for (uint i; i < size; i++) {
        arr[i] = new uint256[](size);
    }
    // ...
}

This compiles but creates some nonsense data structure. Can anyone provide some guidance? The fact that this is possible via constants leads me to think there's no fundamental barrier, I just can't figure out the syntax for passing size via a variable. Thank you!!

1 Answer 1

5
uint256 size = 10;

function initArray() public pure {
    uint256[][] memory arr = new uint256[][](size);
    for (uint i; i < size; i++) {
        arr[i] = new uint256[](size);
    }
    // ...
}

The issue in above code is you are trying to access storege variable size in pure function initArray which is not possible. You should understand the difference between view and pure function. A view function will read the storage but will not change it and a pure function does not need access to the storage and will not change it.

I tried the following code to achieve what you expect but while executing initArray function I am getting VM exception.

pragma solidity ^0.4.24;

contract Foo {
    uint256 n = 10;
    function initArray() public view  {
        uint[][] memory result = new uint[][](n*n);
        for (uint i = 0; i < n; i++){
            for(uint j = 0; j < n; j++){
                result[i][j] = 1;
            }
        }

    }
}

You can achieve the functionality of 2D arrays using a 1D array as following and it is working as expected

pragma solidity ^0.4.24;

contract Foo {
    uint256 n = 10;
    function initArray() public view  {
        uint[] memory result = new uint[](n*n);
        for (uint i = 0; i < n; i++){
           for(uint j = 0; j < n; j++){
                result[(i*9)+j]=1; 
            }
        }

    }
}

I am able to create 2D array in memory. Please refer the following code for the same :

pragma solidity ^0.4.24;

contract Foo {
    uint256 n = 10;
    function initArray(uint k,uint l) public view returns(uint)  {
        uint[][] memory arr = new uint[][](n);
        for (uint i=0; i < n; i++) {
            uint[] memory temp = new uint[](n);
            for(uint j = 0; j < n; j++){
                    temp[j]=i+j; 
                }
            arr[i] = temp;
        }
        // ...
        return arr[k][l];
    }
}

Hope it helps!

5
  • Mm, thanks for the point about pure -- I've updated the question. And interesting approach -- I suppose one could use a larger 1D array and abstract away the dimensions through indexing logic. I would ideally like to use a proper 2D array, though, to make the code more semantic. Sep 10, 2018 at 21:08
  • @kronosapiens , I am able to create 2D array in memory. Please refer the code added Sep 12, 2018 at 10:09
  • Hi @asvisosila, I tried your code but ended up with the same "nonsense" results I had earlier -- a 2D array of [[736], [3], [4], [5], [6]] values each. Sep 13, 2018 at 14:35
  • @kronosapiens, can you please share the code that you have tried? Sep 13, 2018 at 14:40
  • @kronosapiens I am wondering how you are able to validate that this is a "nonsense" data structure? I am able to retrieve a value stored at every index of an array which makes it "sensible" data structure 2D array. Sep 14, 2018 at 5:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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