2

I was hoping this would work..

contract Test {

    uint[] private grid;
    uint width = 5;
    uint height = 10;

    constructor() { 
        grid = new uint[width * height];
    }
}

Ideally I would used a fixed-length array but set the size dynamically. Otherwise I will have to hardcode the size into the contract which is not ideal.

2 Answers 2

2

You need to use this syntax:

grid = new uint[](width * height);

I refactored your code and this works:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

contract Test {

    uint[] public grid;
    uint constant width = 2;
    uint constant height = 3;
    uint constant MAX_ELEMENTS = width * height;
    uint currentIndex;

    constructor() { 
        grid = new uint[](MAX_ELEMENTS);
    }

    function addElement(uint element) public {
        // This will fail if someone tries to add more than MAX_ELEMENTS elements. Using `.push` would not fail, but would add more elements than MAX_ELEMENTS.
        grid[currentIndex] = element;
        ++currentIndex;
    }

    function getGrid() public view returns(uint[] memory) {
        return grid;
    }

}
2
  • 1
    just FYI -- this works with arrays of uints, thank you! But not with an array of structs :-/
    – p0pps
    Commented Sep 10, 2022 at 1:29
  • Using this syntax is enough while declaring the array of struct: User[5] users;; Commented Sep 10, 2022 at 1:52
0

Regarding your other concern, that it did not work with an array of struct, here is the way to do it (read the comments):

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

contract Contract {

    struct User {
        uint256 id;
        string name;
    }

    User[5] users;

    uint256 public userCount;

    function addUser(uint256 id, string calldata name) public {
        // Will revert if the userCount is greater than 5 since we declared the `users` array to be of size 5
        // The .push method does not work on this array either, since we declared it with a size of 5
        users[userCount++] = User(id, name);
    }

}

No need to manually assign an array of struct in the constructor. As long as you declare it in the storage like User[5] users; is enough.

For your grid example, it would look like this:

contract Test {

    //uint[] public grid;
    uint public constant width = 2;
    uint public constant height = 3;
    uint public constant MAX_ELEMENTS = width * height;
    uint public currentIndex;

    Grid[MAX_ELEMENTS] public grids;

    struct Grid {
        uint256 index;
    }

    function addElement(uint element) public {
        // This will fail if someone tries to add more than MAX_ELEMENTS elements. Using `.push` would not fail, but would add more elements than MAX_ELEMENTS.
        grids[currentIndex] = Grid(element);
        ++currentIndex;
    }

    function getGrid() public view returns(Grid[MAX_ELEMENTS] memory) {
        return grids;
    }

}
2
  • 1
    I think this answer misses the point of the question... if grid was a struct, and we had public vars for width and height, how can we declare the array of grids with MAX_ELEMENTS
    – p0pps
    Commented Sep 10, 2022 at 14:30
  • I didn't know what properties would your Grid struct have, so I didn't create an example. But I updated the answer and created a struct Grid with a uint256 index; member as an example. Take a look. Commented Sep 10, 2022 at 15:07

Your Answer

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

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