The class is a reference type, and variables in a class can be types by value. For example:

class Car { public int maxSpeed; public Car(int max) { maxSpeed = max; } } 

Where is maxSpeed stored - on the stack or on the heap?

  • What are your assumptions? - Grundy
  • in a heap, how do you imagine stacking? - etki
  • one
    In general, there is Eric Lippert 's answer to a similar question - Grundy
  • one
    Possible duplicate question: The question of the structure in C #! - ߊߚߤߘ
  • one
    @Arhad there is another question. just the answer is partially suitable :) - PashaPash

3 answers 3

The question itself is caused by two problems.

  • quite common, but in general, the incorrect statement "value-type variables are stored on the stack"
  • a little confusion in terminology - class fields are not “variables” - not local variables.

The fact is that at the level of the C # language there is no concept of "stack" and "pile". There are two kinds of types:

  • Reference. The value of a variable or field of a class of this type stores the memory address for which the type instance lies. An instance of itself usually lies in a heap. An example is strings.
  • Value types. The value of a variable or class field stores the value directly. An example is int.

The concept of a stack is at the level of .NET / IL. Local variables in IL .NET layer methods are stored on the stack. The variable C # is not always converted to the IL method variable. This happens if:

  • there are no closures on it
  • it is declared in the non-async method
  • many more different conditions caused by the implementation features of a specific C # compiler.

Type fields are stored as part of the type instance itself. They physically lie in the piece of memory that is allocated for a specific instance of the type. Those. if the instance itself is on the stack (for example, it is an instance of the structure), then the field is stored on the stack. If the instance is in the heap, then the field is in the heap.

Specific examples

  • int a is declared in the method - it is right on the stack
  • The method has string s declared - the variable in the stack is the address of the string in the heap.
  • The method declares Car c - the variable of the stack contains the address of the Car object. The object itself is in a heap. Part of the object in the heap is the maxSpeed ​​field, in it lies the value of speed.
  • The method declared int [] arr - the variable in the stack is the address of the array in the heap. Right in the array object in the heap are the values ​​of individual cells.
  • Point structure declared with X / Y fields. The method declared the variable Point p - in the variable in the stack is the structure itself, with all the fields.
  • on the last point, the question about the structure: The structure of Point is declared with fields X / Y, if the method changes the value of the fields, why they do not change after the fact, but only in the method itself? - user210691
  • @ user210691 because the structure is the value type, a copy of the structure is passed to the method, not a link to the original. in the same way, the variables of type int passed to the method do not change from the outside. - PashaPash
  • You can prompt one more thing: but if a reference type is specified in the structure - for example. instance of the class, then where is it in the heap is obtained? (a link is created in the stack to the object in the heap, if I understood correctly?) Thank you! - user210691
  • @ user210691 yes, that's right - PashaPash

Translation of the answer to a similar question in English

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's not entirely true that "type-values ​​are always on the stack." If this were true, they would be called "stack types" (stack types) and "heap types" (heap types).

The truth is that it all depends on the implementation details. Different implementations of frameworks can choose to use their stack or heap, as they want. Below is an example of how this is implemented by Microsoft:

  • the value of a reference variable indicates the value in the heap. Links are basically 32 or 64 bit integer.

  • the value of a meaningful variable is the value itself.

  • local variable values ​​are stored on the stack, as long as these variables are not in an iterator block, or are not closed in an anonymous method or lambda expression. In these cases, the values ​​of local variables are stored on the heap. Of course, as long as these variables are not thrown away by the optimizer, in this case they are not stored anywhere. Or maybe they can be transferred to registers and in this case they will not be on the stack or on the heap.

  • instance values ​​of reference types and static variables are stored on the heap.

maxSpeed is a field, therefore, stored in a heap.

The only thing going on the stack is local variables (and temporary variables generated by the compiler) that are not closed in lambda functions or anonymous methods, and are not in an iterator block. And, of course, jitter can not use the stack, but put everything into registers if there are enough free registers.

But, in fact, I have to ask: why are you worried about what goes on the stack, and what on the heap? Only what we can quickly put into it goes into the stack, everything else goes to the heap.

  • I want to figure it out for myself, now it's clear - thanks! - user210691
  • @ user210691, the questions at the end are also part of the translation :-D they are also present in Eric Lippert's original answer - Grundy

Class objects are stored on the heap. And what is a class instance? In essence, type and set of variables.

And the stack stores those variables that are declared inside functions / methods. Hence the problem of stack overflow due to excessive recursive function calls (see the site name :) ).