[Ethereum] the right way to create a struct instance inside a function

arraysgo-ethereummappingsoliditystruct

I read somewhere that if you create a storage variable inside a function, it could overwrite another existing one in the global scope of the smart contract, is that true?

So, if I wanted to create a new struct variable inside a function, and then push it to an array, should I create it in the storage space or memory space?

Like this:

MyStruct storage newStruct;
... // modifiying newStruct variables
myStructsArray.push(newStruct);

Or like this:

MyStruct memory newStruct;
... // modifiying newStruct variables
myStructsArray.push(newStruct);

Same question for when wanting to add a newly instantiated struct to a mapping:

MyStruct storage/memory newStruct;
...
MyStructMapping[index] = newStruct;

Best Answer

If you try to assign a memory struct into a local storage variable the compiler will give you an error:

// This doesn't work, because it would need to create a new temporary 
// unnamed struct in storage, but storage is "statically" allocated.
// MyStruct storage newStruct = MyStruct();

Instead you need to use a memory variable:

// This works.
MyStruct memory newStruct = MyStruct();

If you have a state variable (or an array/mapping containing this struct), you can assign it to a local storage variable):

// Reference type local variables are storage by default, 
// you can omit the storage keyword.
MyStruct newStruct = stateStruct;
// Any assignments to fields in newStruct will be written to storage.

I read somewhere that if you create a storage variable inside a function, it could overwrite another existing one in the global scope of the smart contract, is that true?

I think the compiler prevents such cases as it doesn't allow creating temporary unnamed storage variables.