1

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
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!

  • 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. – kronosapiens Sep 10 '18 at 21:08
  • @kronosapiens , I am able to create 2D array in memory. Please refer the code added – Soham Lawar Sep 12 '18 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. – kronosapiens Sep 13 '18 at 14:35
  • @kronosapiens, can you please share the code that you have tried? – Soham Lawar Sep 13 '18 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. – Soham Lawar Sep 14 '18 at 5:57

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.