title: Why Does SetString Take Less Memory in Delphi (with Unicode)?
body: <p>This is Delphi 2009, so Unicode applies.</p>
  
  <p>I had some code that was loading strings from a buffer into a StringList as follows:</p>
  
  <pre><code>      var Buffer: TBytes; RecStart, RecEnd: PChar; S: string;
  
        FileStream.Read(Buffer[0], Size);
  
        repeat
           ... find next record RecStart and RecEnd that point into the buffer;        
  
           SetString(S, RecStart, RecEnd - RecStart);
           MyStringList.Add(S);
        until end of buffer
  </code></pre>
  
  <p>But during some modifications, I changed my logic so that I ended up adding the identical records, but as a strings derived separately and not through SetString, i.e.</p>
  
  <pre><code>      var SRecord: string;
  
        repeat
          SRecord := '';
          repeat
            SRecord := SRecord + ... processed line from the buffer;
          until end of record in the buffer
  
          MyStringList.Add(SRecord);
        until end of buffer
  </code></pre>
  
  <p>What I noticed was the memory use of the StringList went up from 52 MB to about 70 MB. That was an increase of over 30%. </p>
  
  <p>To get back to my lower memory usage, I found I had to use SetString to create the string variable to add to my StringList as follows:</p>
  
  <pre><code>      repeat
          SRecord := '';
          repeat
            SRecord := SRecord + ... processed line from the buffer;
          until end of record in the buffer
  
          SetString(S, PChar(SRecord), length(SRecord));
          MyStringList.Add(S);
        until end of buffer
  </code></pre>
  
  <p>Inspecting and comparing S and SRecord, they are in all cases exactly the same. But adding SRecord to MyStringList uses much more memory than adding S.</p>
  
  <p>Does anyone know what's going on and why the SetString saves memory?</p>
  
  <hr>
  
  <p>Followup.  I didn't think it would, but I checked just to make sure.</p>
  
  <p>Neither:</p>
  
  <pre><code>  SetLength(SRecord, length(SRecord));
  </code></pre>
  
  <p>nor </p>
  
  <pre><code>  Trim(SRecord);
  </code></pre>
  
  <p>releases the excess space. The SetString seems to be required to do so.</p>