Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StringBuilder and capacity?

I have created test application to test, Is StringBuilder copy data to another instance and grow it buffer when its length is more than current capacity and verify in ildasm.exe but it seem identical.

How to verify StringBuilder will copy its data into new instance and grow the buffer by the specified limit?

like image 425
Anonymous Avatar asked Jul 17 '26 00:07

Anonymous


2 Answers

Capacity represents the contiguous memory allocated to the StringBuilder. Capacity can be >= length of the string. When more data is appended to the StringBuilder than the capacity, StringBuilder automatically increases the capacity. Since the capacity has exceeded (that is contiguous memory is filled up and no more buffer room is available), a larger buffer area is allocated and data is copied from the original memory to this new area.

It does not copy data to new 'instance' but to new 'memory location'. The instance remains the same but points to the new memory location.

Edit FYI: Default capacity of StringBuilder if not specified during creation is 16

If you wanna see the memory locations for StringBuilder then you can debug your applications and check the memory using Debug > Windows > Memory. You can actually see the address of each and every byte stored in your StringBuilder when Append stmt runs.

If you need to get the locations programatically this link might help.

like image 181
SO User Avatar answered Jul 22 '26 04:07

SO User


If you want to inspect how StringBuilder is implemented, just fire up Reflector and look at it. The implementation for StringBuilder.Append(string) is as follows

public StringBuilder Append(string value)
{
   if (value != null)
   {
      string stringValue = this.m_StringValue;
      IntPtr currentThread = Thread.InternalGetCurrentThread();
      if (this.m_currentThread != currentThread)
      {
         stringValue = string.GetStringForStringBuilder(stringValue, stringValue.Capacity);
      }
      int length = stringValue.Length;
      int requiredLength = length + value.Length;
      if (this.NeedsAllocation(stringValue, requiredLength))
      {
         string newString = this.GetNewString(stringValue, requiredLength);
         newString.AppendInPlace(value, length);
         this.ReplaceString(currentThread, newString);
      }
      else
      {
         stringValue.AppendInPlace(value, length);
         this.ReplaceString(currentThread, stringValue);
      }
   }
   return this;
}

Look at the section with NeedsAllocation, GetNewString and so forth to find what you're looking for.

like image 39
Brian Rasmussen Avatar answered Jul 22 '26 03:07

Brian Rasmussen