1

Can anybody please tell me the total number of string instances created in memory for below example ? Brief explanation would be appreciated a lot.

My code:

 String A = "1" + "2" + "3" ;  /* total number of strings in memory = ?? */

 String B = "1" + "2" + "1" ;  /* total number of strings in memory = ?? */

 string one = "1";

 string two = "2";

 string three = "3";

 String C = one + two + three;   /* total number of strings in memory = ?? */

 String D = one + two + one;    /* total number of strings in memory = ?? */
akhil kumar
  • 1,598
  • 1
  • 13
  • 26
Parashuram
  • 1,498
  • 2
  • 16
  • 36

2 Answers2

4

From the C# documentation on string concatenation:

When you concatenate string literals or string constants by using the + operator, the compiler creates a single string. No run time concatenation occurs.

This means that your concatenations create only one string each, so in total your example produces 7 strings in memory:

String A = "1" + "2" + "3" ;  // 1 (concatenation of literals)
String B = "1" + "2" + "1" ;  // 1 (concatenation of literals)

string one = "1"; // 1
string two = "2"; // 1
string three = "3"; // 1

String C = one + two + three; // 1 (concatenation of string constants)
String D = one + two + one; // 1 (concatenation of string constants)

// = 7 strings in total

However, if doing the concatenation in a loop, more strings are generated, e.g.:

for word in text:
    result_string += word // Bad! Creates a new string in each iteration

In this case it is better to use StringBuilder.append:

System.Text.StringBuilder builder = new System.Text.StringBuilder();
for word in text:
    builder.Append(word) // Good! Just appends to the string builder
x squared
  • 3,173
  • 1
  • 26
  • 41
3

Let's look code IL in the IL DASM

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       54 (0x36)
  .maxstack  3
  .locals init ([0] string A,
           [1] string B,
           [2] string one,
           [3] string two,
           [4] string three,
           [5] string C,
           [6] string D)
  IL_0000:  nop
  IL_0001:  ldstr      "123"
  IL_0006:  stloc.0
  IL_0007:  ldstr      "121"
  IL_000c:  stloc.1
  IL_000d:  ldstr      "1"
  IL_0012:  stloc.2
  IL_0013:  ldstr      "2"
  IL_0018:  stloc.3
  IL_0019:  ldstr      "3"
  IL_001e:  stloc.s    three
  IL_0020:  ldloc.2
  IL_0021:  ldloc.3
  IL_0022:  ldloc.s    three
  IL_0024:  call       string [mscorlib]System.String::Concat(string,
                                                              string,
                                                              string)
  IL_0029:  stloc.s    C
  IL_002b:  ldloc.2
  IL_002c:  ldloc.3
  IL_002d:  ldloc.2
  IL_002e:  call       string [mscorlib]System.String::Concat(string,
                                                              string,
                                                              string)
  IL_0033:  stloc.s    D
  IL_0035:  ret
} // end of method Program::Main

As you can see, there are 5 string constants

"123", "121", "1", "2", "3"

and two strings obtained by concatenation. Total 7.

Although A and C (B and D) strings are the same, but they are different instances in memory.


To Arghya C.

If we apply the unsafe code and change the value of the variable A:

Console.WriteLine(A + " " + C);

fixed (char* p = A)
{
    p[1] = 'x';
}

Console.WriteLine(A + " " + C);

we get the following output:

123 123
1x3 123

As you can see, only the variable A has changed, but the C variable retained its value. This proves that they are different copies.

However, if we write this:

String A = "1" + "2" + "3";
String C = "123";

аfter executing unsafe code above we get the following:

123 123
1x3 1x3

That is, in this case, the variables A and C keeps a reference to the same instance of the string.

At first I wrote the wrong answer, because I thought the compiler is smart enough to understand at compile-time that String C = one + two + three; concatenates constants and will create reference on the same string.

Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49
  • 1
    Alexander you didn't mention two string that are returned by `Concat` method invokation so it's actually 7 strings, not 5 – Fabjan Sep 19 '15 at 13:52
  • @AlexanderPetrov From your answer, it seems like there will be only 5 string instances. Can you please update your answer and explain how there are 7 strings? Thanks! – Arghya C Sep 21 '15 at 14:07
  • @Fabjan Are you saying there will be seven string instances (A, B, one, two, three, C, D) but they will actually refer to 5 memory locations (C,D pointing to A,B) ? – Arghya C Sep 21 '15 at 14:10
  • @ArghyaC - please, see update. Sorry for my bad English. – Alexander Petrov Sep 21 '15 at 17:02
  • @AlexanderPetrov Thanks for the explanation! And your English is fine :) – Arghya C Sep 21 '15 at 18:51