# Reference Types and Data Locations in Solidity

By [Jeff](https://paragraph.com/@jeff-8) · 2022-09-28

---

Reference Types
---------------

In Solidity, some types are very simple so that when you use them (such as declaring variables, calling functions, etc), they are just copied. These types include `int`, `uint`, `bool`, `address`, and they are usually called **value types**.

On contrast, when you use other complicated types (`sturct`, `array`, `mapping`), you must be carefully to make sure that if you are creating a **reference** to it, or you are **copying** it from one data location to another. A **reference** is the same as a **pointer** in some other languages. It’s cheap, but when you modify a referent, the referenced value will also be modified, because you are changing the underlying value.

Data Locations
--------------

The reference types can be copied between three data locations, and when you use reference types, you must explicitly provide the data area.

*   `memory` - Whose lifetime is limited to a function call. It is initialized as a clean area at the beginning of a function call, and will be cleared at the end of the function call.
    
*   `storage` - State variables are stored here, and their lifetime is limited to the lifetime of the contract. This is the most expensive one.
    
*   `calldata` - Special data location that contains the function arguments. It is read-only, so if you need to modify the arguments, you can use `memory` so that it will copy the arguments from `calldata` to `memory`. This one is the cheapest.
    

Assignment Behavior
-------------------

*   Assignments between `storage` and `memory` (or from `calldata`) always create an independent copy.
    
*   Assignments from `memory` to `memory` only create references. This means that changes to one memory variable are also visible in all other memory variables that refer to the same data.
    
*   Assignments from `storage` to a local storage variable also only assign a reference.
    
*   All other assignments to `storage` always copy. Examples for this case are assignments to state variables or to members of local variables of storage struct type, even if the local variable itself is just a reference.
    

e.g.

    contract A {
        // The data location of x is storage
        // State variables' data locations can be ommited
        uint[] x;
    
        // `argArray` is copied from `calldata` to `memory`
        function f(uint[] memory argArray) public {
            // Copy from `memory` to `storage`
            x = argArray;
            // Data location of y is `storage`
            // y is a reference (or pointer) to x
            // Any modifying of x or y influence the other
            uint[] storage y = x;
            // Copy from `storage` to `memory`
            uint[] memory z = x;
    
            // Handling over a reference of x to the function
            g(x);
            // Creates a copy from `storage` to `memory`
            h(x);
        }
    
        function g(uint[] storage a) internal {}
    
        function h(uint[] memory b) internal {}
    }

---

*Originally published on [Jeff](https://paragraph.com/@jeff-8/reference-types-and-data-locations-in-solidity)*
