When I have an empty StringBuilder
with a capacity of 5 and I write "hello, world!" to it, does the C# standard specify the new capacity of the StringBuilder
? I have a vague memory that it's twice the new string's length (to avoid changing the capacity with every new appended string).

- 98,240
- 88
- 296
- 433

- 9,295
- 8
- 22
- 21
-
4this is not specified in any standard, its just an implementation detail – BrokenGlass Sep 25 '11 at 19:02
-
StringBuilder is not part of the C# language. It is part of the .net libraries. – David Heffernan Sep 25 '11 at 19:50
-
possible duplicate of [How does the StringBuilder decide how large its capacity should be?](http://stackoverflow.com/questions/4495855/how-does-the-stringbuilder-decide-how-large-its-capacity-should-be) – bzlm Sep 25 '11 at 19:55
-
What makes you curious about this implementation detail? – jason Sep 26 '11 at 01:23
-
@Jason: The "curious" in your question is the answer. – Vlad Vivdovitch Sep 26 '11 at 07:24
-
@Vlad Vivdovitch: Fair enough. – jason Sep 26 '11 at 07:37
3 Answers
Depends what version of .NET you're talking about. Prior to .NET 4, StringBuilder used the standard .NET strategy, doubling the capacity of the internal buffer every time it needs to be enlarged.
StringBuilder was completely rewritten for .NET 4, now using ropes. Extending the allocation is now done by adding another piece of rope of up to 8000 chars. Not quite as efficient as the earlier strategy but avoids trouble with big buffers clogging up the Large Object Heap. Source code is available from the Reference Source if you want to take a closer look.

- 1
- 1

- 922,412
- 146
- 1,693
- 2,536
-
It messed up for us when we upgraded our product from .Net 3.5 to .Net 4.5. We were using string builder object as parameter to a native API call through interop. It resulted in buffer overrun issue causing the process to crash. Heap memory was getting corrupted when native API was returning long strings.We started to provide explicit capacity in constructor so that buffer can take care of long strings.Suprisingly it should have been breaking earlier also for long strings but never got reported.Does Interop layer does some trick in .Net 3.5 when we use string builder as buffer for native APIs? – RBT Apr 13 '16 at 11:38
-
That corrupts the GC heap in either runtime version. Such corruption is not necessarily detected, you have to be lucky. Sure, you tend to get more lucky in .NET 4 – Hans Passant Apr 13 '16 at 11:46
The C# standard will not specify the behavior of a BCL library class as it has nothing to do with the language specification.
As far as I know the actual behavior is not defined in any specification and is implementation specific.
AFAIK, The MS implementation will double the capacity once the current capacity has been reached.
See this and this previous SO questions.
Update:
This has been changed in .NET 4.0. as described by Hans in his answer. Now ropes are used, adding additional 8000 characters at a time.
MSDN, however is very careful to point out that the actual behavior is implementation specific:
The StringBuilder dynamically allocates more space when required and increases Capacity accordingly. For performance reasons, a StringBuilder might allocate more memory than needed. The amount of memory allocated is implementation-specific.
-
2
-
1@Eric - Thanks for correcting me. That and the answer from Hans gave me more detail. – Oded Sep 25 '11 at 20:04
New StringBuilder (.NET 4.5 or higher) allocates an internal buffer m_ChunkChars
requested by the capacity parameter:
public StringBuilder(int capacity)
{
...
m_ChunkChars = new char[capacity];
...
}
So, if capacity is smaller than 40K chars it goes on the Small Object Heap. However (contrary to popular belief), StringBuilder will still allocate on the Large Object Heap if, later, we call sb.Append(...some string larger than 40K chars...);
A possible fix can be found here:
https://github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder

- 1
- 1