2012-03-08 32 views
0

爲什麼操作符在被要求分配0xA8字節時新返回0x1ff8?爲什麼HeapAlloc返回大小爲0x1ff8的緩衝區? (在XP SP3上測試過)

0:016> u IEFRAME!CIntShcut_CreateInstance+0x3 

IEFRAME!CIntShcut_CreateInstance+0x3:  
00d6762c 8bec   mov ebp,esp    
00d6762e 56   push esi  
00d6762f 68a8000000 **push 0A8h**     //asking for 0xA8   
00d67634 be0e000780 mov esi,8007000Eh   
00d67639 e845a0edff call IEFRAME!operator new (00c41683)   
00d6763e 85c0   test eax,eax  
00d67640 59 pop ecx  
00d67641 7419 je IEFRAME!CIntShcut_CreateInstance+0x23 (00d6765c)  

IEFRAME!CIntShcut_CreateInstance+0x15:  
00d6763e 85c0 test eax,eax  
0:008> !heap -p -a eax  

address 00247190 found in  
_HEAP @ 150000  
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state  
00246eb0 0400 0000 [01] 00246eb8 **01ff8** - (busy)  why 0x1FF8 ?? 

EFRAME!operator new: 
00c41683 8bff mov edi,edi  
00c41685 55 push ebp  
00c41686 8bec mov ebp,esp  
00c41688 ff7508 push dword ptr [ebp+8]  
00c4168b 6a08 push 8  
00c4168d ff153c11c300 call dword ptr [IEFRAME!imp_GetProcessHeap (00c3113c)]  
00c41693 50 push tax  
00c41694 ff153811c300 call dword ptr [IEFRAME!imp_HeapAlloc (00c31138)]  

回答

2

這是堆內存池(一個或多個),給您的程序進行(儘管所請求的大小將是一個大一點的某些開銷被添加到每個請求的內存單分配的不是大小的尺寸塊,更多的是在調試中)。

這是因爲從每次分配的系統調用中請求內存開銷很大,因此請求的塊大得多,然後根據需要進行分區,直到堆耗盡空間並需要另一個系統分配爲止。窗口堆通過分配8個字節的多個塊來完成。

請參閱thisthis更深入地瞭解Windows內存堆,而the answer here詳細列出了windbg中的列。

+0

所以我假設「!堆-a」在LFH上使用時不會顯示原始分配。 而不是LFH內部分配顯示「...忙碌 有沒有任何選項來列出原始分配? – gamepe 2012-03-08 07:45:02

+0

我假設我可以啓用頁堆,它會顯示原始分配,但它是唯一的方法嗎? – gamepe 2012-03-08 08:01:47

+0

根據到http://windbg.info/doc/1-common-cmds.html#20_memory_heap,你應該可以使用'!heap -p -all'來列出分配,提供你的原始地址只是在堆中找到它,然後列出有關發現堆的詳細信息 – Necrolis 2012-03-08 08:40:07