33

I saw a question yesterday which raised (for me) another question. Please look at the following code:

public class Class1
{
   int A; //as I uderstand, int is value type and therefore lives in the stack
}

class Class2
{
    Run()
   {
       Class1 instance1 = new Class1();
       instance1.A = 10;  //it points to value type, but isnt this reference (on heap)?
   }
}

Or while creating the instance of Class1, its field types are created on the heap as well? But then I do not understand when it would really be on the stack as almost always you need to create an instance of object in order to use it fields.

trincot
  • 317,000
  • 35
  • 244
  • 286
Mirek
  • 591
  • 2
  • 6
  • 6

3 Answers3

59

as I understand, int is value type and therefore lives in the stack

Your understanding is incorrect. Value types are called "value types" because they are copied by value. Reference types are called "reference types" because they are copied by reference. It is not at all true that "value types always live on the stack". If that were true, they would be called "stack types" and "heap types".

The truth is that this is an implementation detail. Different framework implementations can choose to use the stack and the heap as they like. Here's how the Microsoft implementation does it:

  • the value of a variable of reference type is a reference to heap memory. A reference is basically a 32 bit or 64 bit integer.
  • the value of a variable of value type is its value.
  • the values of local variables are stored on the stack unless the local variables are in an iterator block or are closed-over outer variables of an anonymous method or a lambda expression. In those cases the values of local variables are stored on the heap. Unless of course the local variables can be optimized away, in which case there is no storage at all. Or perhaps they can be enregistered, in which case they are neither on the stack nor the heap, they are in processor registers.
  • the values of instance variables of reference types and static variables are stored on the heap.

Is that clear?

it points to value type, but isn't this reference (on heap)?

The field "A" is of value type. It is a field, and therefore that variable is stored on the heap.

while creating the instance of Class1, its field types are created on the heap as well?

The storage for the instance variables is on the heap, yes.

But then I do not understand when it would really be on the stack as almost always you need to create an instance of object in order to use it fields.

It would never be on the stack. As I said above, the only things that go on the stack are local variables (and compiler-generated temporaries) that are not closed-over locals of a lambda or anonymous method and are not in an iterator block. And of course, the jitter is free to keep them off the stack entirely and put them in registers if there are free registers.

But really, I have to ask, why do you care what goes on the stack and what goes on the heap? What goes on the stack is stuff we can cheaply put on the stack; everything else goes on the heap.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    I have got the book from John Sharp stating that "Value types are created on the stack while reference types on the heap". Do not understand it, too. – Thomas Apr 02 '10 at 16:28
  • "the values of instance and static variables are stored on the heap." Except for struct-typed instance variables of an instance that has been stored on the stack, right? – Joren Apr 02 '10 at 22:45
  • 10
    "why do you care what goes on the stack and what goes on the heap" - because some interviewers very like such questions and a lot of people failed such interviews because it is written everywhere that int variables are always stored on the stack, not "the only things that go on the stack are local variables " – Laserson Oct 03 '13 at 06:47
  • 2
    Good one - `If that were true, they would be called "stack types" and "heap types".` – RBT Aug 22 '16 at 01:19
  • You haven't said anything about storage of `the values of instance variables of value types`? I believe it will be heap only. The fourth bullet point talks only about reference types and static variables. – RBT Aug 22 '16 at 01:32
  • 3
    @RBT: The value of a field of a value type goes wherever the value of the value type is. – Eric Lippert Aug 22 '16 at 03:31
  • could you please explain what you mean by closed-over outer variables? And do you also mean "for loop" when you say iterator block? – Mark Aug 29 '18 at 06:32
  • Also, what do you mean by instance of a static variable lives on heap? Do you mean if I have : struct St { public int Id; public string name; } Class Program{ static void Main(string[] args){ St s; s.Id = 101; s.Name = "Alp" } } Then, s is living on the heap? – Mark Aug 29 '18 at 06:35
  • After reading your complete post, even i feel it hard to understand the logic when would value types go on stack. Any such scenario in C# that we encounter while programming? – Mark Aug 29 '18 at 06:44
  • 1
    This answer is so underrated. It should be marked under a legendary status/must read category. Too many interviewers ask whether some type sits on the stack or the heap. It's an implementation detail that can change over versions or other implementations. And honestly I see no practical use for memorizing this information so therefore...I don't. My answer is usually, "I don't know". This is the nicest response I have over, "This is a truly terrible question. Move on please." Maybe Joel can add this to "The Best Software Writing II" – P.Brian.Mackey Jun 25 '21 at 19:41
  • I care whether objects/structs/references/values... are placed on the stack because stack push/pop is highly efficient (and can reasonably be expected to be more performant than heap allocation and free). https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/performance/#improve-performance-with-ref-safety – Coder Jun 13 '23 at 04:16
10

Local struct (value type) variables are stored on the stack, value type fields of a class are stored on the heap.

Andrew Bezzub
  • 15,744
  • 7
  • 51
  • 73
  • 10
    Unless (1) the local varaible is the closed-over outer local of an anonymous method or lambda expression, or (2) the local is in an iterator block, or (3) the jitter decides to use registers instead of the stack. – Eric Lippert Apr 02 '10 at 15:57
  • what happens to instance1 variable as far as its storage is concerned. It is a reference type but at the same time it is local to the function Run(). Will instance1 be saved on stack or heap? – RBT Mar 17 '15 at 01:11
  • I'm sorry @EricLippert for another comment but I was trying to edit my previous one but couldn't do it timely. Just to add clarity to my question above I want to ask two things 1. where the reference instance1 will be saved. instance1 is just a reference holding a memory address to where the actual object instance is residing 2. where the object, instance of Class1 referred by instance1 will reside. Here the object is an instance of Class1 but has a local scope in Run() method. – RBT Mar 17 '15 at 01:31
3

Ok int is a value type but '1' (what an awful name for a class) is a reference type. This means that any instance of '1' is on the heap.

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216