0

Like what I asked above, I know the new keyword will allocate memory on the Heap. I know basic data types like float, int, bool etc.. live on the stack. But why do you have to use new when you want to allocate data on the Heap? Why when you create an object out of a class you need to use the new keyword? Why when you create basic variables you don't need to use the new keyword? Also do arrays live on the Heap?

This question is specific to C#

David
  • 27
  • 3
  • Because 'Basic variables' are primitives that the OS couldn't do without and Objects are 'user defined'. – Suraj S Jul 15 '17 at 16:11
  • 2
    Possible duplicate of [I don't understand why we need the 'new' keyword](https://stackoverflow.com/questions/38099520/i-dont-understand-why-we-need-the-new-keyword) or [Why do C# and Java bother with the “new” operator?](https://stackoverflow.com/questions/433591/why-do-c-sharp-and-java-bother-with-the-new-operator). – Lance U. Matthews Jul 15 '17 at 16:21
  • Actually, you *can* write something like int x = new System.Int32(); however, for value types (like int), this in general does not allocate memory, but only initializes memory (in many cases stack memory). – Pachelbel Jul 15 '17 at 16:24
  • https://github.com/dotnet/csharplang/blob/master/spec/introduction.md#types-and-variables – Mike Lowery Jul 15 '17 at 16:54

2 Answers2

2

If you have a variable of a reference type, you can either assign it an existing object

b = a; // Where a is another variable.

or assign it a newly created object

b = new A(); // Where A is a type.

or assign it null. null is the only pre-existing constant value of reference types (except for strings).

b = null;

new makes it clear that a new object is created. This also runs the constructor. Whether it is on the heap or the stack is not important. Strings are treated in a special way in C#. Even though they are reference types, they have a value type semantic as they are immutable and have constants (literals) much like value types. You can create them with new so, when you want to convert character arrays to strings, for instance.

A variable of a reference type always contains a reference or null. It means that it always occupies the same amount of memory (either 32-bits or 64 bits, depending on OS and process type).


On the other hand, when you have a value type, you are either assigning a constant value (which has not to be created).

x = 5;

or you are assigning a copy of another value

x = t;

Note that structs are value types as well. If you want their constructor to run, you must create them with new as well.

p = new Point(1, 2);

But struct fields or elements of struct arrays exist without having been created with new. All their fields and properties are initialized to default values automatically.

var points = new Point[10];

creates ten points with coordinates (0, 0). The constructor of the single points is never called.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • 3
    strings are *not* an exception, it just so happens that you almost always get new ones from a function return value or an operator result, rather than calling the constructor. But writing `new string(...)` is occasionally useful, particular when you want a single character repeated N times. – Ben Voigt Jul 15 '17 at 16:35
  • Yes but you do not have to write `s = new String("hello");`. The string constants are created by the compiler. Other reference types don't have constants other than `null`. – Olivier Jacot-Descombes Jul 15 '17 at 16:38
  • Yes, but `s = "hello";` is not really any different from `s = string.Empty;` or `s = thatarray[42];` You're copying a reference to an object that already exists, not creating a new one. If you want a new string object, you have to either call the constructor yourself, or call a function that internally calls the constructor (e.g. `string.Join` or `StringBuilder.ToString` or `string.Concat`). – Ben Voigt Jul 15 '17 at 16:42
  • Of couse technically a string is a reference type and works just as any other reference type. But their immutability and the fact that they have literals give you the illusion that strings work like value types in most situations. They are an exception in the sense that you can work mostly without using the `new` keyword. – Olivier Jacot-Descombes Jul 15 '17 at 17:06
1

First: The new keyword does not "allocate memory on the Heap". The new keyword is used to instantiate an instance, primitives or not.

Second, if you have this;

ClassDefined myClassOrig = new ClassDefined();
ClassDefined myClassCopy = myClassOrig;

You are not using a new keyword to assign myClassOrig to myClassCopy. It's the same for int.

You have :

int myIntOrig = 156;
int myClassCopy = myIntOrig;

The same for other types, like:

string myStringExample = "some string";
Vector3 myVectorExample = Vector3.zero;

The thing is, that 156 or "some string" or Vector3.zero are (as new ClassDefined()) instances/values of something and you are assigning that instance/value to your variables.

When you use an int value like 156 you are assigning the value of 156 to your variable myIntOrig. 156 by itself its using space in memory and doesn't need a new 156 to be instantiated.

mayo
  • 3,845
  • 1
  • 32
  • 42