3

I know that struct is a value type , that means it defined on stack .

But I can do A a = new A(); (A my struct of course). and it defined on heap , and only the reference variable is on stack.

Can you explain me this one please .

2
  • 3
    Using new to instantiate a struct does not change the way that the struct is stored or how memory is allocated to it. new does not automatically imply that it's allocating memory on the heap. Commented Dec 13, 2010 at 15:33
  • @Jim is right. "new" does not mean "allocate on the heap", it means "allocate appropriately and then run the appropriate constructor". How the memory is allocated is up to the runtime. Commented Dec 13, 2010 at 19:43

5 Answers 5

4

Value types are stored on the stack sometimes. It's a complex topic and usually the exact storage of a variable (stack or heap) is irrelevant for programming issues. The real difference between value and reference types lies in their behaviour (for example, value types are always copied by value).

Eric Lippert covers this issue in detail:

Sign up to request clarification or add additional context in comments.

Comments

2

Where a local variable is stored is an implementation detail.
Simple local variables are usually stored in the CPU-registers and/or the stack.

If they are captured in a closure they'll be rewritten into members in a heap allocated object. That's because the lamda might outlive it's creating functions, and thus the variables it uses must be able to live long enough too.

Unlike in C++ in C# the new does not imply a heap allocation. It's just the syntax for calling a constructor.

And calling new on a value-type doesn't have the semantics of a placement new either. It has the semantics of constructing an instance somewhere and then copying it into the target variable.

In my mental model there are two types of storage:

  1. Local storage that can't outlive the return of the function. This includes stack and registers.
  2. Global storage that lives until it isn't referenced anymore. This is usually the heap. But in run-times that do escape analysis it might be put on the stack if the runtime proves that no references will survive the function.

Your example falls into the first kind of storage since you use a value type.

Comments

1

Your code (A a = new A();) creates and initializes the struct. If it is a local variable, it is initialized on the stack. If it is a member variable, it is initialized on the heap as part of the object. Using "new" doesn't necessarily mean a heap allocation in C#/.NET. It depends on the context.

2 Comments

A a=new A() conceptually constructs a new instance of the struct and copies it into a. But of course the compiler can optimize it away. It doesn't get constructed inplace unless the compiler can guarantee that this can't be observed in single threaded code. And for member variables it usually can't.
@Jason - Yes, there is the possibility that the variable, a, could be part of a closure and hoisted by the compiler. This wrinkle seemed beyond what the questioner was asking. As I said, it depends on context.
1

The original assumption that value types live "on the stack" is not correct. However, The Truth About Value Types has been revealed by Eric Lippert:

  1. It is usually stated incorrectly: the statement should be "value types can be stored on the stack", instead of the more common "value types are always stored on the stack".
  2. It is almost always irrelevant. We've worked hard to make a managed environment where the distinctions between different kinds of storage are hidden from the user. Unlike some languages, in which you must know whether a particular storage is on the stack or the heap for correctness reasons.
  3. It is incomplete. What about references? References are neither value types nor instances of reference types, but they are values. They've got to be stored somewhere. Do they go on the stack or the heap? Why does no one ever talk about them? Just because they don't have a type in the C# type system is no reason to ignore them.

Comments

0

But I can do A a = new A(); (A my struct of course). and it defined on heap , and only the reference variable is on stack.

If A is a value type as you say, and a is a method local, it will be allocated on the stack. Unless a is used in a closure -- then it will be allocated as part of a heap-allocated object of a compiler-generated class.

If you want further analysis, you will have to post the definition of the A type as well as the entire method where you define this variable.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.