この質問をスキングした後、まだ質問があります。
私は両方の優れた答えを得ましたが、これが実際にどのように発生するかを見つけるのにまだ問題があります:(どのように障害状況が発生する可能性があります):
例から始めます:
public void Do(string [] g)
{
g=null; //<========
}
void Main()
{
var t=new string[3];
t[0]="1"; t[1]="1"; t[2]="1";
Do( t);
Console.WriteLine ( t.Length);
}
表記された行は別のスレッドで実行できますが、各スレッドには独自の g
変数があります。(そして、配列に項目を追加できないこと
を覚えておいてください。配列の長さは作成時に作成されるためです)
関数 で何をしてもDo
- (どのスレッドでも) 、 Console.Writeline の結果は常に3
( を使用しない限りref
) になります。
実際のコードを見てみましょう:
public static string Concat(params string[] values)
#1 {
#2 if (values == null)
#3 {
#4 throw new ArgumentNullException("values");
#5 }
#6 int totalLength = 0;
#7 string[] strArray = new string[values.Length];
#8 for (int i = 0; i < values.Length; i++)
#9 {
#10 string str = values[i];
#11 strArray[i] = (str == null) ? Empty : str;
#12 totalLength += strArray[i].Length;
#13 if (totalLength < 0)
#14 {
#15 throw new OutOfMemoryException();
#16 }
#17 }
#18 return ConcatArray(strArray, totalLength);
#19 }
私の言い方は、スレッドで #1 にX
なると、このスレッドは永遠に長さ 3 の配列を持つことになります。
別のスレッドが配列の長さを破棄/変更したい場合(配列の長さが固定されているため、方法がわかりません。彼ができることはそれを作成することだけですnull
)-ポインターアドレスの別のコピーがあります。
ここで何かが欠けているに違いありません。
何が欠けていますか?
エラーを引き起こす他のスレッドが実行できるコードは何ですか?(配列をコピーしないと仮定して)。