DEV Community

loading...

Discussion on: Interview question: heap vs stack (C#)

Collapse
akashkava profile image
Akash Kava • Edited

The string type deserves a special mention because it's a reference type but it's primarily passed by copy, not by reference. This is the only such type

This is wrong, string is reference type and it is always passed as reference (and reference is a pointer to actual string contents, this pointer is passed as value, pointer is always on stack when passed/returned in method)

However string is designed to be immutable so you cannot modify it (this is why you feel it is copied, but it is not), imagine if you have 100KB of text in string passing it from one method to another would be time consuming. When you run a method like .ToUpper() etc, this is the time a new string is allocated on heap and its reference is sent to you.

Also literal strings are declared in assembly's resources, which is loaded on the heap, string is not copied and it can never be, it would be worst design ever.

reference types are allocated on the heap while value types are allocated on the stack

This statement is correct (with exception of closure), because fields do not constitute as type, class/structure containing them is a type. If experienced developers do not understand true definition of the type then it is certainly wrong place to work !!

Only in case of closure, every captured variable becomes part of a reference stored on heap.

This is the reason, there are local functions, captured value type variables in local functions are not stored on heap.

So I would recommend shorter sentence,

Fields do not constitute as type, all reference types and all value types captured in lambda are on heap and remaining value types are always on stack.

Collapse
tyrrrz profile image
Alexey Golub Author

This is wrong, string is reference type and it is always passed as reference (and reference is a pointer to actual string contents, this pointer is passed as value, pointer is always on stack when passed/returned in method)
However string is designed to be immutable so you cannot modify it (this is why you feel it is copied, but it is not), imagine if you have 100KB of text in string passing it from one method to another would be time consuming. When you run a method like .ToUpper() etc, this is the time a new string is allocated on heap and its reference is sent to you.

You're completely right, thanks for correcting.

This statement is correct (with exception of closure), because fields do not constitute as type, class/structure containing them is a type. If experienced developers do not understand true definition of the type then it is certainly wrong place to work !!

I'm not sure what your point is here. A reference type (i.e. class) can be declared with a value type field inside of it. The lifespan of the memory allocated for this field cannot be shorter than the lifespan of the memory allocated for the containing type, so both have to be placed on the heap.

Collapse
akashkava profile image
Akash Kava

My point is, you cannot use term value type for a field. Field is a member of type. Members belong where ever the containing type exists that's all (this is well known phenomenon).

Thread Thread
tyrrrz profile image
Alexey Golub Author

My point is, you cannot use term value type for a field. Field is a member of type.

A field is member of a type but also represents an instance of some type as well. The term "value type field" is a field whose type (not the declaring type) is a value type.

For example, see here, you can get the type of a field by getting the value of FieldInfo.FieldType property. You can then check if it's a value type through checking Type.IsValueType property.

Members belong where ever the containing type exists that's all (this is well known phenomenon).

Yes, that's what I said. Hence why saying "value types are allocated on the stack" is not correct, even if you exclude closures.

For example, here's an article by Jon Skeet referencing the subject in the second paragraph.

Thread Thread
akashkava profile image
Akash Kava • Edited

Type is something you can always do typeof(x), you can never do type of (field of (class/struct)). Example,

    struct A {
       ? a;
    }
Enter fullscreen mode Exit fullscreen mode

First of all you can never do typeof(A.a) because a is a field of type, it is not a type !

FieldInfo.FieldType is type of field, field is not type. Again, value type is a type, which you can safely do typeof(int), typeof(string), anything that can sit inside typeof expression is a type, field is not type.

Here, A is a type, since it is a struct, it will always be on stack unless captured by lambda. And whatever may be the type field a, A will always be on stack !! Member of a type is not type !! Field/Method/Property all are member of type and allocation will never depend on them. If a is string, it is reference, but string is a type, a is not type, and A will still sit on stack and contents of string will be on heap and a will store reference and entire object will sit on stack.

Thread Thread
tyrrrz profile image
Alexey Golub Author

You can do A.a.GetType() to get the field type. Field type can be value type. I'm not talking about field being a type.

Forem Open with the Forem app