What happens when you assign reference of local variable inside method to public static variable

StackOverflow https://stackoverflow.com/questions/12478811

Domanda

Meanwhile reading on the internet I learned that static variables always have the same memory address. So when compiling the program, the compiler is going to decide what memory address to assign to the static variables. Reading that made me think about what happens when you do:

class Foo {}

class Program
{
    public static Foo someStaticVar;

    static void Main(string[] args)
    {
        Foo localVariable = new Foo();

        int x = 4;

        someStaticVar = localVariable; // is someStaticVariable still will have the same address?
    } 
    // variable x will be pushed of the stack
    // localVariable will be pushed of the stack
    // what happens then with someStatic var? 
}

I also learned that when declaring variables inside a method they will be pushed to the stack when created and popped out the stack when the method returns. If all that is true then someStaticVar should disappear but it doesn't.

I am sure I must understood something incorrectly. Or maybe on the line someStaticVar = localVariable; is performing a deep copy of that object but I doubt it because there are a lot of questions on the interenet on how to do a deep copy of an object and they are much different than this approach.

È stato utile?

Soluzione

In the example you provided localVariable is only a local variable to the Main method. It falls out of scope once the Main method ends executing. But since you have assigned it to the static field, the Foo instance that was created will continue to live outside of the Main method. And since it is static field it will live even outside of the Program class.

So here's what happens step by step:

static void Main(string[] args)
{
    // an instance of Foo is created and pushed on the heap
    // localVariable is now pointing to the address of this instance
    // localVariable itself is stored on the stack
    Foo localVariable = new Foo();

    // someStaticVar is now pointing to the same location on the heap as
    // the localVariable - the Foo instance created earlier
    someStaticVar = localVariable; 
} 
// at this stage the Main method finishes executing and all local
// variables are falling out of scope. But since you have a static variable
// pointing to the Foo instance that was created inside the Main method this
// instance is not illegible for garbage collection because there are still 
// references to it (someStaticVar).

If someStaticVar was an instance field and not static then the same process will happen except that the instance will fall out of scope once there are no longer any references to the containing class (Program).

Altri suggerimenti

when declaring variables inside a method they will be pushed to the stack when created and popped out the stack when the method returns.

Foo localVariable = new Foo();

will create Foo object on heap, & reference is stored on stack. when method completes, references is removed from stack. Garbage collector will do job of removing Foo from heap as there will be no reference to Foo object. But,

someStaticVar = localVariable;

, will cause, someStaticVar to reference Foo object on heap. Even after method exits, someStaticVar will still be refering Foo object. so, garbage collector wont collect that Foo object. Main thing to remember is , when Reference type's object is created, object is created on heap, & reference is stored on stack.

Questions is "where static field is stored?", object's instance fields are stored on heap, local variables are stored on stacks, but where "static variable exist in memory?"

There is no deep copying of the object: the object itself is stored on the heap, not on the stack. You are correct that someStaticVariable will always have the same address. Your misunderstanding, I believe, is in what's stored at that address.

When you declare a variable of a reference type (any object type, such as Foo in your code), the variable itself isn't the object: it's a variable that stores the address of your object. That address is just a number. So, "the address of someStaticVariable" isn't the address of the Foo itself; it's the address of the address of the Foo.

In the same way, this is why your someStaticVar doesn't "disappear." What happens in your code is that a Foo is created at some address in memory, and localVariable is set to a value that represents the address in memory of the Foo. When you perform someStaticVar = localVariable, what happens is that the address is copied from localVariable to someStaticVar, and thus both variables point at the same Foo. When localVariable disappears, someStaticVar is not affected.

In this case Foo is a class, so it is a reference type. A variable of type Foo is really just a pointer to a location in memory where the Foo object actually is stored.

When saying that the static variable has a constant memory address it is not saying that the value of that memory address is constant. The address of the pointer to the Foo object won't change, but the number (in this case, address) that is stored in that fixed memory location can easily vary between various potential Foo objects (or null).

Beyond that, since C# is a managed language and not an unmanged language, it's not even true to say that the static variable will have a constant memory address. It's certainly possible, but it's really an implementation detail of the memory manager of C# that you shouldn't be relying on.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top