Reputation:
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?
Upvotes: 2
Views: 1068
Reputation: 700322
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;
Upvotes: 0
Reputation: 754715
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.
Upvotes: 1