Arrays
數組 .pop() 上的錯誤
我有一個修改數組的函式,如果我註釋掉 .pop() 行,它通過,如果沒有,我得到這個錯誤:
虛擬機錯誤.revert
程式碼:
function moveShipsToSpace(uint[] memory ships, uint16 fromSpace, uint16 toSpace) public{ for(uint8 i= 0; i<ships.length; i++) { require(containsInSpace(ships[i],fromSpace), "dont have that ship"); // Move the last element into the place to delete whichShipsAtSpace[msg.sender][fromSpace][i] = whichShipsAtSpace[msg.sender][fromSpace][whichShipsAtSpace[msg.sender][fromSpace].length - 1]; // Delete whichShipsAtSpace[msg.sender][fromSpace].pop(); // Insert in new location whichShipsAtSpace[msg.sender][toSpace].push(shipsArray(ships[i])); emit LogUint(ships[i]); } }
另外,如果我傳遞一個數字,它會與 .pop() 一起傳遞,如果我傳遞 2 個或更多它會失敗,所以不確定是什麼問題,請停下來!
它實際上在這裡失敗了:
whichShipsAtSpace[msg.sender][fromSpace][i] = ...
因為您假設索引“i”是數組 ship 和 whichShipsAtSpace 的有效索引
$$ msg.sender $$$$ fromSpace $$. 但事實並非如此。 船舶將始終保持相同的長度,但 whichShipsAtSpace
$$ msg.sender $$$$ fromSpace $$當您從中彈出項目時,長度會減少。在某些時候,變數 i 是 whichShipsAtSpace 的超出範圍索引$$ msg.sender $$$$ fromSpace $$. 要解決此問題,您需要更換:
whichShipsAtSpace[msg.sender][fromSpace][i] = ...
經過 :
whichShipsAtSpace[msg.sender][fromSpace][shipIndexInFromSpace(ships[i])] = ...
其中 shipIndexInFromSpace 是返回船舶索引的函式
$$ i $$在 whichShipsAtSpace 裡面$$ msg.sender $$$$ fromSpace $$大批。 您的程式碼崩潰實際上是一件好事,因為它甚至沒有按照您希望它在目前狀態下執行的操作。由於索引 ‘i’ 指向一艘未知的船和 whichShipsAtSpace 的順序
$$ msg.sender $$$$ fromSpace $$$$ i $$元素正在被轉移,我相信您的程式碼可能會默默地刪除與您打算的不同的船。