OK, I ran a simple test and found out that in a dynamic array, the length of the array is located at the first 32 bytes relatively to the beginning of the array:
Smart Contract:
pragma solidity 0.4.25;
contract MyContract {
function read1() external pure returns (uint a, uint b, uint c) {
uint[3] memory arr;
arr[0] = 111;
arr[1] = 222;
arr[2] = 333;
assembly {
a := mload(add(arr, 0))
b := mload(add(arr, 32))
c := mload(add(arr, 64))
}
}
function read2() external pure returns (uint a, uint b, uint c) {
uint[] memory arr = new uint[](3);
arr[0] = 444;
arr[1] = 555;
arr[2] = 666;
assembly {
a := mload(add(arr, 0))
b := mload(add(arr, 32))
c := mload(add(arr, 64))
}
}
}
Truffle Test:
contract("MyContract", function(accounts) {
it("test", async function() {
const myContract = await artifacts.require("MyContract").new();
await test(myContract.read1);
await test(myContract.read2);
});
async function test(func) {
const [a, b, c] = await func();
console.log(a.toFixed(), b.toFixed(), c.toFixed());
}
});
Printout:
111 222 333 (this is for the `uint[3] memory arr`)
3 444 555 (this is for the `uint[] memory arr = new uint[](3)`)