大家好:
我又仔细看了下《软件调试》中的23章。并做了一些实验。出了个很奇怪的问题:
如果不定义任何的调试标记!gflag -htc -hfc –hpc,New NtGlobalFlag contents: 0x00000000 那么在释放堆的时候,堆既没有被释放,也没有添加到空闲链表当中。但是当进行堆验证的时候,堆却忽然将这2个空闲块释放了。。。
源代码:就是分配了1个私有堆,之后再从这个堆上分配了2次堆块,并且均释放。
void heaperr() { HANDLE hHeap=NULL; int bRet = false; void* p = NULL;
hHeap=HeapCreate(0, 4096, 0); p = HeapAlloc(hHeap, 0, 128); bRet=HeapFree(hHeap, 0, p);
p = HeapAlloc(hHeap, 0, 256); bRet=HeapFree(hHeap, 0, p);
bRet=HeapValidate(hHeap, 0, NULL); bRet=HeapDestroy(hHeap);
return ; }
这是第二次分配堆块512B,这里也可以看到上次分配的堆块128B并没有被释放
0:000> !heap 3a0000 -a
Index Address Name Debugging options enabled
5: 003a0000
Segment at 003a0000 to 003b0000 (00003000 bytes committed)
Flags: 00001002
ForceFlags: 00000000
Granularity: 8 bytes
Segment Reserve: 00100000
Segment Commit: 00002000
DeCommit Block Thres: 00000200
DeCommit Total Thres: 00002000
Total Free Size: 000001fd
Max. Allocation Size: 7ffdefff
Lock Variable at: 003a0608
Next TagIndex: 0000
Maximum TagIndex: 0000
Tag Entries: 00000000
PsuedoTag Entries: 00000000
Virtual Alloc List: 003a0050
UCR FreeList: 003a0598
FreeList Usage: 00000000 00000000 00000000 00000000
FreeList[ 00 ] at 003a0178: 003a2020 . 003a2020
003a2018: 00108 . 00fe8 [10] - free
Segment00 at 003a0640:
Flags: 00000000
Base: 003a0000
First Entry: 003a0680
Last Entry: 003b0000
Total Pages: 00000010
Total UnCommit: 0000000d
Largest UnCommit:0000d000
UnCommitted Ranges: (1)
003a3000: 0000d000
Heap entries for Segment00 in Heap 003a0000
003a0000: 00000 . 00640 [01] - busy (640)
003a0640: 00640 . 00040 [01] - busy (40)
003a0680: 00040 . 01808 [01] - busy (1800)
003a1e88: 01808 . 00088 [01] - busy (80)
003a1f10: 00088 . 00108 [01] - busy (100)
003a2018: 00108 . 00fe8 [10]
003a3000: 0000d000 - uncommitted bytes.
这是第二次释放堆块,这里看出,和第一次一样堆没有释放,而且在堆空闲链表中也没有记录。
0:000> !heap 003a0000 -a
在进行堆验证后,可以看到前2次堆块全部被释放了。这是为什么呢???
Total Free Size: 0000022f
FreeList[ 00 ] at 003a0178: 003a1e90 . 003a1e90
003a1e88: 01808 . 01178 [10] - free
003a1e88: 01808 . 01178 [10]
但是,为什么在free list中也没有记录呢?还有为什么一检测堆,就会被释放掉了呢??
哦,谢谢Thomson,张老师。
在此对Thomson表示抱歉,我一开始没有认真琢磨,你的回复。