views:

515

answers:

2

Just to make sure I'm understanding shallow copies of reference types correctly and that I'm not constructing a huge memory leak here:

// Adds text to the beginning of the log RTB
// Also keeps the log RTB trimmed to 100 lines
var lines = new string[rtbLog.Lines.Length + 1];
lines[0] = "text";
Array.Copy(rtbLog.Lines, 0, lines, 1, rtbLog.Lines.Length);

if (lines.Length > 100)
{
    Array.Resize(ref lines, 100);
}

rtbLog.Lines = lines;

This would firstly copy the refs to the strings in rtbLog.Lines into lines. Then it would copy the first 100 refs from lines into a new string array.

Meaning the array that rtbLog.Lines was originally referencing, the array initially referenced by lines (before the resize), and lastly any strings not contained in lines (after the resize), all get garbage collected. (I hope that makes sense)

Correct?

+1  A: 

The Array.Resize method is a bit of a misnomer. It should really be named CopyToNewArrayWithSize. Under the hood, this API will create a new array and copy the specified data into that array. The new array is then returned by reference.

As for garbage collection. By reseting the Lines property to the new array, you did successfully remove the original reference to the array. As long as there are no other references to the array, it will be garbage collected at some point in the future.

JaredPar
A "yes" would have sufficed, but thank you for taking the time to explain in a different way! :) As long as the strings that I'm "popping" off the end get GC'ed (provided they're not referenced elsewhere of course), I'm happy.
A: 

Yes, the original array and strings that are not used any more are garbage collected just fine.

If you calculate the size that you want before creating the array, you don't have to call Resize (as that will create yet another copy of the array).

// Adds text to the beginning of the log RTB
// Also keeps the log RTB trimmed to 100 lines
int size = Math.Min(rtbLog.Lines.Length + 1, 100);
string[] lines = new string[size];
lines[0] = "text";
Array.Copy(rtbLog.Lines, 0, lines, 1, size - 1);
rtbLog.Lines = lines;
Guffa
Good point, thank you.