There is a smaller limit on the number of elements that can be in a dynamic memory array than the number of elements that can be in a dynamic storage array or a non-dynamic storage array.
https://blog.soliditylang.org/2020/04/06/memory-creation-overflow-bug :
Starting from Solidity version 0.6.5 the maximum allocation size for dynamic memory arrays is 2**64-1. Attempting to allocate larger arrays now directly reverts.
However this is specifically for dynamic arrays that are allocated in memory (not storage), as a local variable in a function, of the form
contract A {
function x() {
uint256[] myArray = new uint256[](someLargeNumber);
}
}
Storage arrays are actually just a hashmap (implemented internally using a trie), also with a length field that sets the upper bound for indices, and they can store up to 2**256-1 elements (given an Ethereum node the size of the universe...).
Storage arrays can be dynamic too:
contract B {
uint256 dynamicStorageArray[];
uint256 nonDynamicStorageArray[3];
}
But neither of these storage array forms has the limit of 2**64-1 elements, both can hold 2**256-1 elements.
Another notable difference: dynamic storage arrays support push() and pop(). Dynamic memory arrays do not support this.
Internally, both memory arrays and storage arrays store the length of the array in their first memory location, as a uint256 (so the limit on the number of elements in a dynamic memory array is imposed by compiler-generated logic, not by the inability to represent or store more than this number of elements). array.length always returns a uint256, no matter the type of array or where it is stored out of memory or storage.
gasconstraints ? – Andy B. Jul 16 '18 at 17:442**64-1" https://blog.soliditylang.org/2020/04/06/memory-creation-overflow-bug -- however, oddlyarray.lengthreturns auint256. – Luke Hutchison May 26 '22 at 09:06