sam
sam

Reputation: 91

how String object is allocate memory without having new keyword or constructor?

In C# if we want to create a variable of type string we can use:

string str="samplestring"; // this will allocate the space to hold the string

In C#, string is a class type, so if we want to create an object, normally we have to use the new keyword. So how is allocation happening without new or constructors?

Upvotes: 7

Views: 13360

Answers (7)

Nick Hill
Nick Hill

Reputation: 4917

When you write

string str="samplestring";

compiler will generate two instructions:

  1. Firstly, ldstr gets a string literal from the metadata; allocates the requisite amount of memory; creates a new String object and pushes the reference to it onto the stack.
  2. Then stloc (or one of it's short forms, e.g. stloc.0) stores that reference in the local variable str.

Note, that ldstr will allocate memory only once for each sequence of characters.

So in example below both variables will point at the same object in memory:

// CLR will allocate memory and create a new String object
// from the string literal stored in the metadata
string a = "abc";

// CLR won't create a new String object. Instead, it will look up for an existing
// reference pointing to the String object created from "abc" literal
string b = "abc";

This process is known as string interning.

Also, as you know, in .NET strings are immutable. So the contents of a String object cannot be changed after the object is created. That is, every time you're concatenating string, CLR will create a new String object.

For example, the following lines of code:

string a = "abc";
string b = a + "xyz";

Will be compiled into the following IL (not exactly, of course):

  1. ldstr will allocate memory and create a new String object from "abc" literal
  2. stloc will store the reference to that object in the local variable a
  3. ldloc will push that reference onto the stack
  4. ldstr will allocate memory and create a new String object from "xyz" literal
  5. call will invoke the System.String::Concat on these String objects on the stack
  6. A call to System.String::Concat will be decomposed into dozens of IL instructions and internal calls. Which, in short, will check lengths of both strings and allocate the requisite amount of memory to store the concatenation result and then copy those strings into the newly allocated memory.
  7. stloc will store the reference to the newly created string in the local variable b

Upvotes: 9

tukaef
tukaef

Reputation: 9214

When you creates a string using literals, internally, depending on your assembly is marked with NoStringInterning flag or not, it's looks like:

String str = new String("samplestring");
// or with NoStringInterning
String str = String.Intern("samplestring");

Upvotes: 0

Moslem Ben Dhaou
Moslem Ben Dhaou

Reputation: 7005

Strings are in fact reference types. The variable hold a reference to the value in the memory. Therefore you are just assigning the reference and not the value to the object. I would recommend you to have a look at this video from Pluralsight (you can get a free 14 days trial)

Pluralsight C# Fundamentals - Strings

Disclaimer: I am in no way related to Pluralsight. I am a subscriber and I love the videos over there

Upvotes: 2

user1279293
user1279293

Reputation: 5

In java if you write something like that:

String s1 = "abc";
String s2 = "abc";

memory will be allocated for "abc" in so called string pool and both s1 and s2 will refer to that memory. And s1 == s2 will return true ("==" compares references). But if you write:

String s1 = new String("abc");
String s1 = new String("abc");

s1 == s2 will return false. I guess in c# it'll be the same.

Upvotes: -4

goric
goric

Reputation: 11875

This is simply the C# compiler giving you a shortcut by allowing string literals.

If you'd rather, you can instantiate a string by any number of different constructors. For example:

 char[] chars = { 'w', 'o', 'r', 'd' };
 string myStr = new String(chars);

Upvotes: 6

Spevy
Spevy

Reputation: 1325

According to the MS documentation you do not need to use the new command to use the default string constructor.

However this does work.

char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);

c# Strings (from MSDN programming guide)

Upvotes: 3

Frank Thomas
Frank Thomas

Reputation: 2514

While everything is an object in .net there are still primitive types (int, bool, etc) that do not require instantiation. as you can see here, a string is a 4byte address ref pointing to a vector/array structure that can extend to up to 2GB. remember strings are unmutable types so when you change a string you are not editing the existing variable, but instead allocating new memory for the literal value and then changing your string pointer to point to your new memory structure. hope that helps

Upvotes: 1

Related Questions