Dynamic creation of an array in a view Function

Knowing the problems with the arrays in solidity and its high cost of gas, I thought of creating an array dynamically in a function that will look for the values in a mapping indexed through a counter. I consider that this option is cheaper than the direct storage in an array.

However, it gives me error. It doesn’t specify which one because it would compiles me perfectly. I am using a structure as type of the array and I don’t know if this is a problem, although I think it shouldn’t be.

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

contract Estructuras {

/// ///     STRUCT ///

    struct Estructura {
        string cadena;
        uint id;
        address direccion;
    }

    Estructura datosUsuario;


    mapping(uint => Estructura) public users;
    mapping(address => bool) public permisos;

    uint public contador;

    function crearUsuario(uint _idNFT, string memory _nombre) public  {

            require(!permisos[msg.sender], "Usted ya esta registrado");
            contador++;
            Estructura memory newEstructura  = Estructura(_nombre, _idNFT, msg.sender);
            users[contador] = newEstructura;
            permisos[msg.sender] = true;


    }

    function createArray() public view returns(Estructura[] memory){

            Estructura[] memory array;
            for(uint i = 0; i < contador; i++){
            array[i] = users[i + 1];      
            }
            return array;

    }

}

Where is my mistake?

Have you tried array.push(users[i + 1]);

Yes, I have tried it and it also gives the same error.

How about:

function createArray() public view returns(Estructura[] memory) {
  Estructura[] memory array = new Estructura[](contador);
  for(uint i = 0; i < contador; i++){
     array[i] = users[i + 1];
   }
   return array;
}
1 Like

works!!! The main difference is that your function has the static array with length definition…
It seems that it needs to know what it has to reserve memory to send the array. Fantastic this forum is the best without a doubt to clear doubts. Not only Moralis. Thank you very much.

Great. Pleased I could help!

1 Like

Do you think that the reason why a static array is needed instead of a dynamic array is to be able to know what memory reservation is to be set for the execution of the function?

Might be worth trying setting the size of the array to zero and using push instead!

what!!
This has to be tested… I’ll let you know the result.

TypeError: Member "push" not found or not visible after argument-dependent lookup in struct 

No works.

 function createArray() public view returns(Estructura[] memory) 
      {
            Estructura[] memory array = new Estructura[](0);
            for(uint i = 0; i < contador; i++){
                array[i].push(users[i + 1]);
            }
            return array;
    }

I still think it needs a static array to hold space in memory. And therefore we can’t use the push and pop methods.

Unfortunately it seems so!