第5章看了一部分,所理解的东西记录如下:
在win2k下调试堆中的内存分配机制
一、申请内存
堆中用heapcreate申请内存区后,用heapalloc申请内存块。
首次申请的内存分配在偏移为0x0688的地方。该地址存储在freelist[0]表中,偏移地址为0x0178。再申请内存依次向后分。
所分内存以8个字节为单位进行分配,最小8字节。在所分配内存块前,还有8字节的块首。因此一次申请所需要的内存大小还需再加8。
申请3个字节( h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,3)) 后,
内存状态为
00520170 00 00 00 00 00 00 00 00 98 06 52 00 98 06 52 00 ........?R.?R.
00520180 80 01 52 00 80 01 52 00 88 01 52 00 88 01 52 00 €R.€R.?R.?R.
00520190 90 01 52 00 90 01 52 00 98 01 52 00 98 01 52 00 ?R.?R.?R.?R.
00520680 02 00 08 00 00 01 0D 00 00 00 00 00 78 01 52 00 .........xR.
00520690 2E 01 02 00 00 10 00 00 78 01 52 00 78 01 52 00 .....xR.xR.
005206A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
005206B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
内存申请代码:
h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,3);
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,5);
h3 = HeapAlloc(hp,HEAP_ZERO_MEMORY,6);
h4 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
h5 = HeapAlloc(hp,HEAP_ZERO_MEMORY,19);
h6 = HeapAlloc(hp,HEAP_ZERO_MEMORY,24);
二、释放内存
释放内存后,内存会按大小收回freelist表中。free[]表的每个表头用8个字节存储双向指针。
释放h1后,内存状态为
00520170 00 00 00 00 00 00 00 00 08 07 52 00 08 07 52 00 ........R.R.
00520180 80 01 52 00 80 01 52 00 88 06 52 00 88 06 52 00 €R.€R.?R.?R.
00520190 90 01 52 00 90 01 52 00 98 01 52 00 98 01 52 00 ?R.?R.?R.?R.
005201A0 A0 01 52 00 A0 01 52 00 A8 01 52 00 A8 01 52 00 ?R.?R.?R.?R.
00520680 02 00 08 00 00 00 0D 00 88 01 52 00 88 01 52 00 ......?R.?R.
00520690 02 00 02 00 00 01 0B 00 00 00 00 00 00 01 52 00 ... ......R.
005206A0 02 00 02 00 00 01 0A 00 00 00 00 00 00 00 52 00 ...........R.
释放的内存链接到0x188处。0x178为free[0],0x188为free[2],即16字节区域。
再释放h3,h5后,内存状态为
00520170 00 00 00 00 00 00 00 00 08 07 52 00 08 07 52 00 ........R.R.
00520180 80 01 52 00 80 01 52 00 88 06 52 00 A8 06 52 00 €R.€R.?R.?R.
00520190 90 01 52 00 90 01 52 00 C8 06 52 00 C8 06 52 00 ?R.?R.?R.?R.
005201A0 A0 01 52 00 A0 01 52 00 A8 01 52 00 A8 01 52 00 ?R.?R.?R.?R.
005201B0 B0 01 52 00 B0 01 52 00 B8 01 52 00 B8 01 52 00 ?R.?R.?R.?R.
00520680 02 00 08 00 00 00 0D 00 A8 06 52 00 88 01 52 00 ......?R.?R.
00520690 02 00 02 00 00 01 0B 00 00 00 00 00 00 01 52 00 ... ......R.
005206A0 02 00 02 00 00 00 0A 00 88 01 52 00 88 06 52 00 ......?R.?R.
005206B0 02 00 02 00 00 01 08 00 00 00 00 00 00 00 00 00 ............
005206C0 04 00 02 00 00 00 0D 00 98 01 52 00 98 01 52 00 ......?R.?R.
005206D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
h1,h3释放后,链接在free[2]表中,每个节点用8个字节存储双向指针(前4个字节指向后,后4个字节指向前),组成双向链表(内存块中用于块首的8个字节不用来存指针):
0x188链接0x688,0x688链接0x6A8,0x6A8链接0x188。
0x18B链接0x6A8,0x6AB链接0x688,0x68B链接0x188。
h5链接在free[4]处,链接方法相似。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!