1
function mloadTest1() public pure returns(bytes memory) {
  bytes memory a;

  assembly {
      a :=mload(0x40)
  }

  return a; // 0x20
}

function mloadTest2() public pure returns(bytes32) {
    bytes32 a;
    assembly {
        a := mload(0x40)
    }
    return a; // 0x80
}

mload(x) is a Yul code that reads 32 bytes from offset x in memory. And Solidity defaults to free memory points from 0x00 to 0x60, with 0x80 stored at 0x40.

I ran the code in two cases. I thought bytes memory a would return 0x80 (free memory point), but it returns 0x20. bytes32 a returns 0x80 as normal.

2 Answers 2

1

They are different types, and behave differently.

  • bytes is a dynamic array of bytes, allocated in memory or storage.
  • bytes32 is a fixed array of 32 bytes, allocated in the stack, it could be memory or storage in an array or struct
-1

First, You have small typos of function name as both of function name as mloadTest1. If you call both functions in the same transaction, the second function will override the memory contents set by the first one.

About your questions of bytes memory a, in this function, bytes memory a; declares a dynamic byte array, but it doesn't initialize its length. The line a := mload(0x40) reads 32 bytes from the memory location 0x40 and assigns it to the dynamic byte array a. The value at memory location 0x40 is whatever was previously stored there.

In more details:

Solidity, by default, allocates free memory from 0x00 to 0x60. The value at memory location 0x40 is initially set to 0x20 when your contract starts executing.

When you read 32 bytes starting from 0x40 (mload(0x40)), you are effectively reading the 32 bytes from 0x40 to 0x5F. This includes the value 0x20.

So, a ends up being a dynamic byte array with a length of 0x20. The value 0x20 comes from the initial state of the memory location 0x40.

5
  • Solidity's free memory point 0x40 contains 0x80 by default, so I thought that 0x80 would be stored in bytes memory a, but the result was 0x20. Is it correct that 0x20 is stored as the initial value in free memory point 0x40 from what you said?
    – imelon2
    Commented Jan 6 at 17:18
  • Maybe my explaination make a confusion. It is correct that 0x20 is stored as the initial value in free memory point 0x40 in Solidity. This is because the free memory pointer is initialized to point to the value 0x20 when the contract is deployed. Moreover, the mload instruction in Solidity Assembly does not read the value of the memory directly at the specified address. Instead, it reads the value of the free memory pointer and then dereferences the address to read the actual value. Thus, it actually reads 0x20, not 0x80.
    – tqdpham96
    Commented Jan 6 at 17:28
  • The latest Solidity documentation says that 0x80 is stored in free memory pointer(0x40), not 0x20 docs.soliditylang.org/en/latest/internals/layout_in_memory.html
    – imelon2
    Commented Jan 6 at 17:34
  • Yes, you are right, but 0x80 stored in free memory pointer "when a contract is deployed". This means that there are 0x80 bytes of free memory available to the contract. However, the point is when you call the "mload" instruction, it reads the value of the free memory pointer "before" any memory has been allocated. Since no memory has been allocated yet, the value is 0x20 (which is the beginning of the allocated memory)
    – tqdpham96
    Commented Jan 6 at 17:50
  • If 0x20 is stored in the free memory pointer as you say, why does bytes32 a in mloadTest2() return 0x80?
    – imelon2
    Commented Jan 7 at 3:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.