単純なギザギザ配列を作成しました:
int[][] a = new int[2][];
for (int i = 0; i < 2; i++)
{
a[i] = new int[3];
for (int j = 0; j < 3; j++)
a[i][j] = i * 3 + j;
}
その後、アプリケーションのデバッグを開始し、メモリ内のこの配列構造 (x86) を調べました。
0x03022478 0 // SyncBlockIndex (a)
0x0302247C 0x61B8D5BC // TypeHandle (a)
0x03022480 2 // a.Length
0x03022484 0x617A4C8A // ???
0x03022488 0x03022494 // a[0]
0x0302248C 0x030224AC // a[1]
0x03022490 0 // SyncBlockIndex (a[0])
0x03022494 0x61B9C448 // TypeHandle (a[0])
0x03022498 3 // a[0].Length
0x0302249C 0 // a[0][0]
0x030224A0 1 // a[0][1]
0x030224A4 2 // a[0][2]
0x030224A8 0 // SyncBlockIndex (a[1])
0x030224AC 0x61B9C448 // TypeHandle (a[1])
0x030224B0 3 // a[1].Length
0x030224B4 3 // a[1][0]
0x030224B8 4 // a[1][1]
0x030224BC 5 // a[1][2]
SyncBlockIndexes、TypeHandles、Lengths、Elements のほぼすべてのデータを理解しています。しかし、私は1行だけを理解できません:
0x03022484 0x617A4C8A // ???
それは何ですか?
更新 1:
このアドレス値を別のSOSコマンドで解決しようとしました。
!DumpArray 0x617A4C8A
<Note: this object has an invalid CLASS field>
Invalid object
!DumpAssembly 0x617A4C8A
Fail to fill Assembly
!DumpClass 0x617A4C8A
Invalid EEClass address
!DumpDomain 0x617A4C8A
Fail to fill AppDomain
!DumpMD 0x617A4C8A
617a4c8a is not a MethodDesc
!DumpMT 0x617A4C8A
617a4c8a is not a MethodTable
!DumpObj 0x617A4C8A
<Note: this object has an invalid CLASS field>
Invalid object
!DumpSig 0x617A4C8A
!DumpSig <sigaddr> <moduleaddr>
更新 2:
参照型の配列では、この DWORD は配列要素 MethodTable のアドレスを意味する必要があります。たとえば、object[10]
この DWORD は の MethodTable のアドレスですSystem.Object
。ただし、int[][]
この DWORD の場合、有効な MethodTable アドレスではありません (チェックには SOS コマンド DumpMT を使用します)。