Why can't I return dynamic array in Solidity?

Viewed 4200

I am trying to return a list of addresses by declaring an array and pushing to it in a for loop. However, Solidity doesn't like when I try to return a dynamic array.

    function listMyPromises() public returns(uint256[] memory ){ //lists all my past promises
  uint256[] memory List;
  for(uint i=0; i<table.length; i++){
    if(table[i].userAddress==msg.sender){
      List.push(uint256(table[i].friendAddress));
    }
  }
    return List;
}

Solidity is not allowing me to return a array stating that

TypeError: Data location must be "memory" or "calldata" for return parameter in function, but none was given. However When I add memory in the return parameter I get the error: TypeError: Member "push" is not available in uint256[] memory outside of storage

I have no clue what to do.

1 Answers

Solidity doesn't allow resizing (e.g. by using .push()) a memory array.

You need to calculate the size beforehand and then create a fixed-size memory array.

Source: docs


So the result is possibly going to look like this

function listMyPromises() public returns(uint256[] memory ){ //lists all my past promises
    uint256 count = getCount();
    uint256[] memory List = new uint256[](count);
    
    uint256 j;
    for (uint i = 0; i < table.length; i++) {
        if(table[i].userAddress==msg.sender){
            List[j] = uint256(table[i].friendAddress);
            j++;
        }
    }

    return List;
}

function getCount() internal view returns (uint) {
    uint count;

    for (uint i = 0; i < table.length; i++) {
        if (table[i].userAddress == msg.sender) {
            count++;
        }
    }
    
    return count;
}

Depending on the datatypes wrapped in the table[i] struct, you might also run into another error. The friendAddress suggests that it's a type address, but it cannot be converted to uint256.

Related