在VC6里(Release模式),在堆里分配的内存都有个header.请问这个header能传递给我们什么信息,即它的每个字节有什么意义?这是我的实验,这8个字节是我们申请内存前的8个字节.
分配4字节时:
03 00 01 01  00 01 08 00分配5字节时:
03 00 01 01  00 01 08 00分配9字节时:
03 00 01 01  00 01 08 00分配100字节时:
0F 00 21 00  00 01 08 00分配200字节时:
1B 00 21 00  00 01 08 00分配600字节时:
4D 00 21 00  00 01 08 00分配1200字节时:
97 00 21 00  00 01 08 00分配5000字节时:
73 02 01 01  00 01 08 00
=========================================
1.不管分配多少,后4个字节都是00 01 08 00,这四个字节代表什么意义?2.大致可以看出,前两个字节乘以8,略大于我们申请的内存,比如:
  0x0097 * 8 = 1208 (申请1200时)
  0x0273 * 8 = 5016 (申请5000时)
  所以说,前两个字节乘以8,就是我们得到的空间(比我们申请的略大一点,可能是为了对齐),这个结论对吗?
  这个因子8,跟00 01 08 00里的08有关系吗??3.有了前两个问题,那就剩下第三、四字节了,它们代表什么?看得出它们只有两种情况:0x0021,0x0101.谢谢啦!请高手不吝赐教

解决方案 »

  1.   

    来贴一篇,希望对你有用:)原创:isno(isno) 
    来源:http://www.xfocus.org 
     以下所有程序的测试环境为:
    中文版Windows 2000 + SP2
    VC++ 6.0二、Windows的HEAP管理机制简述
    同LINUX一样,Windows的HEAP区是程序动态分配一块内存区域。程序员一般调用C函数malloc/free或者C++的new/delete或者WIN32 API函数HeapAlloc/HeapFree来动态分配内存,这些函数最终都将调用ntdll.dll中的RtlAllocateHeap/RtlFreeHeap来进行实际的内存分配工作,所以我们只需要分析RtlAllocateHeap/RtlFreeHeap就行了。对于一个进程来说可以有多个HEAP区,每一个HEAP的首地址以句柄来表示:hHeap,这也就是RtlAllocateHeap的第一个参数。每个HEAP区的整体结构如下:+-------------------------------------------------------------------+
    | HEAP总体管理结构区 |    双指针区    |        用户分配内存区       |
    +-------------------------------------------------------------------+
    ^                    ^
    |_hHeap              |_hHeap+0x178heap总体管理结构区存放着一些用于HEAP总体管理的结构,这不是我们所关心的。双指针区存放着一些成对出现的指针,用于定位分配内存以及释放内存的位置,这可能是某种树结构,我还没完全搞清楚。用户分配内存区是用户动态分配内存时实际用到区域,也这是HEAP的主体。当我们调用RtlAllocateHeap(HANDLE hHeap,DWORD dwFlags,SIZE_T dwBytes)来分配内存时将进行以下操作:
    对参数进行检查,如果dwBytes过大或小于0都按照出错处理,根据dwFlags来设置一些管理结构;
    检查是否为DEBUG程序,对于DEBUG的程序与实际运行的程序每个内存块之间的结构是不同的,所以我们下面说到的都是以RELEASE版编译的实际运行的程序(不是在MSDEV中调试的程序);
    根据要分配的内存的大小(dwBytes)决定不同的内存分配算法,我们只分析小于1024 bytes的情况;
    从双指针区找到用户内存区的末尾位置,如果有足够的空间分配所需的内存,就在末尾+dwBytes+8的位置放置一对指针来指向双指针区的指向用户内存区末尾位置的地方;
    在后面同时设置双指针区的指向用户内存区末尾位置的指针指向进行完分配之后的用户内存区末尾位置。这么说可能有点绕,不过这跟HEAP溢出没有太大的关系,所以我们就不细究了。两块连续分配的内存块之间并不是紧挨着的,而是有8字节的管理结构,最末尾的一块内存后面还另外多了8字节的指针指向双指针区,就是上面提到过的。假设有以下程序:
    buf1 = HeapAlloc(hHeap, 0, 16);
    buf2 = HeapAlloc(hHeap, 0, 16);
    连续分配了两块16字节内存,实际在内存中(用户分配区)的情况是这样的:第一次分配后:
    +-----------------------------------------------+
    |       buf1         |   8 byte   |4 byte|4 byte| 
    +-----------------------------------------------+
    |      用户内存      |  管理结构  |   两个指针  |第二次分配后:
    +---------------------------------------------------------------------------------+
    |       buf1         |   8 byte   |       buf2         |   8 byte   |4 byte|4 byte| 
    +---------------------------------------------------------------------------------+
    |      用户内存      |  管理结构  |      用户内存      |  管理结构  |   两个指针  |在第二次分配内存的时候会利用第一块内存管理结构后面那两个指针进行一些操作,其中会有一次写内存的操作:77FCB397                 mov     [ecx], eax
    77FCB399                 mov     [eax+4], ecx这时的eax和ecx分别指向:
    +-----------------------------------------------+
    |       buf1         |   8 byte   |4 byte|4 byte| 
    +---------------------------------^------^------+
    |      用户内存      |  管理结构  |_eax  |_ecx  |