0

I need to add elements to a resizable myArray and then delete the myArray. I don't know what the length of myArray will be before the loop, and it's not possible to resize a memory array; that leaves me with a storage array.

In v0.6.0 a breaking change was made to make member-access to length of arrays always read-only, so I can no longer simply call myArray.length = 0 to effectively delete the array. And calling delete myArray throws the compilation error: TypeError: Unary operator delete cannot be applied to type uint256[] storage pointer.

pragma solidity 0.6.0;

contract Hello {

    function withdraw() external {
        uint256[] memory blocktimes = getBlocktimes();
        uint256[] storage myArray;

        for (uint256 i = 0; i < blocktimes.length; i++) {
            if (blocktimes[i] <= block.timestamp) {
                // do something
            } else {
                myArray.push(blocktimes[i]);
            }
        }

        if (myArray.length > 0) {
            // assign myArray to something else, then...
            delete myArray;
        }
    }
}

Also, the blocktimes array is bounded, so please save the "anti-pattern" pestering :) I'm simply asking how I can append elements to a resizable array, and then delete it.

9
  • Also, the blocktimes array is not even shown in your question. Please add it in order to make the code an MVP (at least for solc 0.5.x). Jul 5, 2020 at 18:11
  • You also have a serious issue with declaring uint256[] storage myArray; inside a function. First, It's not really clear from your question why you need to allocate this array when you immediately delete it at the end. It is also not really clear why this is a storage array and not a memory array to begin with. A storage variable in a function must be initialized to point to (reference) some state variable which actually resides in storage. You don't have such state variable in your code, and you are (subequently) not initializing your local storage variable to point to such a state variable. Jul 5, 2020 at 18:19
  • 1
    If it's just a compilation issue, then you can solve it with uint256[] memory myArray = new uint256[](blocktimes.length);, then uint256 j = 0; before the loop, and then myArray[j++] = blocktimes[i]; inside the loop. Jul 5, 2020 at 18:25
  • 2
    BTW, this line uint256[] storage myArray; is exceptionally dangerous. blog.b9lab.com/storage-pointers-in-solidity-7dcfaa536089#9955 Jul 5, 2020 at 19:43
  • 1
    Why do you wanna remove zeros? Just let them be, and when you iterate that array, simply stop at the first zero that you encounter. Jul 5, 2020 at 20:37

1 Answer 1

0

When you declare a storage pointer without assigning it to anything and use it, it produces weird behavior (it would overwrite to your existing storage slots). That's why you need to give it a storage.

pragma solidity 0.6.3;

contract Hello {
    // temporary array
    uint256[] myArray;
    
    function withdraw() external {
        uint256[2] memory blocktimes = getBlocktimes();

        for (uint256 i = 0; i < blocktimes.length; i++) {
            if (blocktimes[i] <= block.timestamp) {
                // do something
            } else {
                myArray.push(blocktimes[i]);
            }
        }

        if (myArray.length > 0) {
            // assign myArray to something else, then...
            delete myArray;
        }
    }
    
    function getBlocktimes() private pure returns(uint256[2] memory) {
        return [uint256(10000000000),uint256(10000000000)];
    }
}

Definitely, you might achieve // do something. But doing the above is very inefficient, since you are charged gas for using the storage. The better solution is to not use a temporary array myArray.

Also you mentioned // assign myArray to something else, then..., if you are anyways going to assign it, why not directly try to write to it in the else block of your for loop? It would save plenty of gas here.

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.