56

I've been looking through the code of Etherdice and noticed that some variables are declared like

ParserResult memory result;

and I haven't found the keyword "memory" in any documentation. What I found on here was this explanation:

They are analogous to memory and hard drive storage in a computer. The contract can use any amount of memory (as long as it can pay for it of course) during executing its code, but when execution stops, the entire content of the memory is wiped, and the next execution will start fresh. The storage on the other hand is persisted into the blockchain itself, so the next time the contract executes some code, it has access too all the data it previously stored into its storage area.

Does the "memory" declaration actually make the value be stored in "memory"? Aren't all local variables inside a function stored just in memory and global variables always stored in the blockchain? And what is the relation to this explanation of "Memory" here?

2 Answers 2

71

The Solidity FAQ on "memory" is highly recommended reading in entirety, and a snippet is provided below.

The Ethereum Virtual Machine has three areas where it can store items.

The first is “storage”, where all the contract state variables reside. Every contract has its own storage and it is persistent between function calls and quite expensive to use.

The second is “memory”, this is used to hold temporary values. It is erased between (external) function calls and is cheaper to use.

The third one is the stack, which is used to hold small local variables. It is almost free to use, but can only hold a limited amount of values.

For almost all types, you cannot specify where they should be stored, because they are copied everytime they are used.

The types where the so-called storage location is important are structs and arrays. If you e.g. pass such variables in function calls, their data is not copied if it can stay in memory or stay in storage. This means that you can modify their content in the called function and these modifications will still be visible in the caller.

There are defaults for the storage location depending on which type of variable it concerns (source):

state variables are always in storage
function arguments are always in memory
local variables of struct, array or mapping type reference storage by default
local variables of value type (i.e. neither array, nor struct nor mapping) are stored in the stack

The FAQ has code samples to help explain further.

A common mistake is to declare a local variable (of struct, array or mapping) and assume that it will be created in memory, although it will be created in storage.

The subtleties explanation of memory explains gas costs for using memory, which is a byte-array that "starts off zero-size, but can be expanded in 32-byte chunks by simply accessing or storing memory at indices greater than its current size".

5
  • 1
    Thanks a bunch! I swear that the search on their docs page did not behave yesterday.
    – uberlaufer
    Commented Mar 1, 2016 at 12:40
  • 4
    No problem, it's a fundamental but very important topic so it's good you asked!
    – eth
    Commented Mar 1, 2016 at 12:42
  • @eth It's been a long time but... I see I can declare local variables like uint without the data location. I understand that it is required for arrays/mappings/structs (as stated in the docs + your answer), yet why is the code complaining about the string?
    – mdmb
    Commented Jan 24, 2022 at 12:37
  • 1
    @Ancinek does ethereum.stackexchange.com/questions/28333/… help? I have not tracked many changes to Solidity but generally it has followed the trend of being more explicit rather than implicit.
    – eth
    Commented Jan 25, 2022 at 7:06
  • @eth Thanks for the response! I actually asked the question on SO (stackoverflow.com/questions/70833745/…) and after digging in I found an article explaining strings in Solidity (coders-errand.com/working-with-strings-in-solidity) – they basically are arrays, so it then makes sense to explicitly add memory when playing with them e.g. inside functions :)
    – mdmb
    Commented Jan 26, 2022 at 10:56
0

In Solidity, the keyword memory is used to declare variables that are stored in the EVM's memory, which is a temporary, short-lived storage area that is used during contract execution. Memory variables are only valid for the duration of a function call and are deleted when the call ends. They are not stored on the blockchain and are not accessible after the function call ends.

On the other hand, storage variables are stored in the contract's storage and are persisted on the blockchain. They are accessible from any function in the contract and remain valid for the lifetime of the contract.

Here is an example to illustrate the difference between memory and storage variables:

pragma solidity ^0.8.3;

contract Example {
    uint public foo;
    uint[] public bar;

    function setFoo(uint _foo) public {
        foo = _foo;
    }

    function setBar(uint[] memory _bar) public {
        bar = _bar;
    }
}

In this example, foo is a storage variable because it is not declared with the memory keyword. It is stored in the contract's storage and can be accessed from any function in the contract.

On the other hand, bar is a memory variable because it is declared with the memory keyword. It is stored in memory and is only valid for the duration of the function call. When the setBar function ends, the value of bar will be deleted from memory.

It is generally a good idea to use memory variables whenever possible, because they are faster and cheaper to access than storage variables. Storage variables should be used only when the data needs to be persisted on the blockchain

1

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.