Click here to Skip to main content
15,909,193 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
Explain the whole process when a constructor of an instance class is called
what changes take place in stack and heap
Posted

You mention the constructor specifically, like it is some special case, it is not. When it comes to memory allocation there is no difference whether your code is in a constructor or method.

Lets go though how the memory allocation works, kinda.
C#
public class AClass
{
    private int _myField;

    public AClass()
    {
        int i = 0; // 1
        _myFields = 0; // 2

        AClass aClass = new AClass(); // 3
        // Note StackOverflowException here, this is just to show there is no 
        // difference between memory allocation in a constracutor and a method.
    }

    public static AClass Create()
    {
        int i = 0; // 4

        AClass aClass = new AClass(); // 5

        aClass._myField = 0; // 6

        return aClass;
    }
}


1 - is stored on the stack
2 - is stored in the heap
3 - the reference is stored on the stack and the object is stored on the heap.
4 - is stored on the stack
5 - the reference is stored on the stack, and the object is stored on the heap.
6 - is stored in the heap

As I said this is how it kinda works, and I say kinda because you can't be 100% sure of the storage location.
Microsofts implementation of C# stores all short-lived values on the stack or registers and long-lived values on the heap. Those that the compiler is short-lived is assumed to be long-lived.

One important thing to note. Many books and other sources say value types are always stored on the Stack, this is not true. Value types are only stored on the Stack when they are short-lived.

If you're using some other C# implementation like Mono all that is stated above is null and void. Mono might do the exact same thing, it most likely does not. For all I know Mono stores all memory in the Heap.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 20-Sep-11 17:37pm    
I did not see you added a solution to this question, too. Good detailed overview, my 5.
I think my solution emphasizes some different detail, please see.
--SA
Simon Bang Terkildsen 20-Sep-11 18:21pm    
I didn't realize that the OP also posted the other question.
You posted a good answer I especially like you pointed out that just because it works like that in C# doesn't mean it works like that in other .NET languages, as I didn't point that out specifically, only that mono might not do it like described.
Sergey Alexandrovich Kryukov 20-Sep-11 18:43pm    
Wow! What do you know about different Mono behavior? I'm writing on Mono right now... sounds disturbing...
--SA
Simon Bang Terkildsen 21-Sep-11 11:35am    
Oh I don't know how the behavior is when using Mono. I just tried to emphesize that other implementations of C# does not necesarely match Microsofts CLR implementation of C#. Mono could for all I know not have a Stack and only allocate memory in the Heap.
Now Mono does have a stack, but I would be very surprised if it determined the exact same values to be short-lived (stoed on the Stack) as Microsofts CLR implementation of C#.
The expression "a constructor of an instance class" is very inaccurate. Before a constructor is called there is no instance. There is a variable of some class, but it does not refer to any instance yet. The instance is created by the constructor and assigned to a variable. Since that moment, it starts referencing some class instance. Before the constructor call, the variable can be null or reference some other instance. That instance had nothing to do with the constructor you call; it can be even of different type — compile-time type of the variable does not have to be the same as the (run-time) type of the instance — this is a fundamental OOP aspect which allows for late binding and polymorphism.

Moreover, the variable of the class type is not required to exist. You can call a constructor disregarding the return value. This can be done when only the side effect of constructor call is needed.

You see, so much of conceptual clarification is needed, even before getting to stack and heap.

Now, as to stack and heap, nothing specific to classes happens.

Stack is pushed and popped the same way as in the case of any method call, no difference. Again, there is time before call, during the execution of constructor body and after the call. As it usually happens, the stack before and after the call looks identical, only the values of the returned instance and out/ref parameters are changed if they were on stack. During the execution of constructor body, the stack is made deeper (instruction pointer decreases) by the number of bytes needed for all the parameters and stack (local) variables of the constructor code. The size allocated for each parameter depends on parameter size for in parameters and is equal to the size System.IntPtr for out/ref parameters. During the execution, the stack is pushed and popped the same way each time some method or property is called by the constructor code, directly or indirectly.

With the heap, the memory needed to hold the instance is allocated, plus some of the heap is allocated by the the execution of constructor body, as it can create instances of other objects.

All this is related specifically to C# but not to entire .NET. In C++/CLI (and apparently raw IL), even the referenced objects do not have to be allocated on heap. C++/CLI can support value semantics even for reference types; it also can work with heap and CLR references exactly as C# or freely combine these to models.

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900