我创建了简单的锯齿状数组:
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。但我不能只理解一行:
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 来检查它)。