views:

40

answers:

2

Should StringBuilder.Capacity be set to the maximum number of .NET characters, without regards to null termination, or must it be set one higher to reserve space for a null terminator when using P/Invoke.

The natural reaction is that it should be set one higher, but it seems like P/Invoke is supposed to automatically compensate. In fact this is actually documented right here: http://msdn.microsoft.com/en-US/library/s9ts558h(v=VS.100).aspx

The reason for this question is that most examples are not strictly consistent with the above documentation. Almost always they are coded:

StringBuilder sb = new StringBuilder(dotNetChars + 1);
SomeWindowsAPI(sb, sb.Capacity);

Instead of:

StringBuilder sb = new StringBuilder(dotNetChars);
SomeWindowsAPI(sb, sb.Capacity + 1);

(I realize that some APIs handle the buffer size parameter differently. Assume that the API handles this the must common way, like GetFullPathName: http://msdn.microsoft.com/en-us/library/aa364963(v=VS.85).aspx)

Using an expression with sb.Capacity directly in the API call seems to be a best practice to avoid a mismatch. The issue is whether or not adding the +1 is correct.

Look around. You'll probably find that the only place showing sb.Capacity + 1 is the MSDN documentation.

Of course, one can allocate on the side of caution with a larger buffer than is strictly necessary, but I would like to know the consensus on how to do this.

A: 

Inside the constructor of StringBuilder, capacity is used like this:

m_ChunkChars = new char[capacity];

This is used together with the m_ChunkLength field to determine the contents of the StringBuilder. This only describes actual characters, not including a terminating character.

So your answer is the + 1 is not necessary.

Pieter
A: 

Probably a certain amount of cargo cult programming going on. Someone picks up the habit, when asked about memory to allocate for strings, of answering "length+1" instead of length. Rather than read the documentation for new circumstances in which you're asked about memory to allocate for strings, the developer just "errs on the safe side" and passes in length + 1. Others who read that code infer the same rule and the practice spreads. It doesn't have to be right to be passed from person to person, just reasonably likely to be right, and not actively harmful.

Kate Gregory