欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
vc 堆管理函數
Windows的“堆”分為默認堆和私有堆兩種。默認堆是在程序初始化時(shí)由操作系統自動(dòng)創(chuàng )建的,所有標準內存管理函數都是在默認堆中申請內存的;而私有堆相當于在默認堆中保留了一大塊內存,用堆管理函數可以在這個(gè)保留的內存區域中分配內存。一個(gè)進(jìn)程的默認堆只有一個(gè),而私有堆可以被創(chuàng )建多個(gè)。
 
默認堆可以直接被使用,而私有堆在使用前需要先創(chuàng )建,使用私有堆有很多好處:
1)可以使用默認堆的函數有多種,而它們可能在不同的線(xiàn)程中同時(shí)對默認堆進(jìn)行操作,為了保持同步,對默認堆的訪(fǎng)問(wèn)是順序進(jìn)行的;而私有堆的空間是預留的,不同線(xiàn)程在不同的私有堆中同時(shí)分配內存并不會(huì )引起沖突,所以整體的運行速度更快。
2)當系統必須在物理內存和頁(yè)文件之間進(jìn)行頁(yè)面交換時(shí),系統的性能會(huì )受到很大的影響,在某些情況下,使用私有堆可以防止系統頻繁地在物理內存和交換文件之間進(jìn)行數據交換,因為將經(jīng)常訪(fǎng)問(wèn)的內存局限在一個(gè)小范圍地址的話(huà),頁(yè)面交換就不大可能發(fā)生,把頻繁訪(fǎng)問(wèn)的大量小塊內存放在同一個(gè)私有堆中就可以保證它們在內存中的位置更近。
3)使用私有堆有利于封裝和保護模塊化的程序。當程序包含多個(gè)模塊時(shí),如果使用標準內存管理函數在默認堆中分配內存,那么所有模塊分配的內存塊是交叉排列在一起的,如果模塊A中的一個(gè)錯誤導致內存操作越界,可能會(huì )覆蓋模塊B使用的內存塊,到模塊B執行時(shí)出錯,我們將很難發(fā)現錯誤的源頭來(lái)自于模塊A。而如果讓不同模塊使用自己的私有堆,那么它們的內存就會(huì )完全隔離開(kāi)了,越界錯誤就很容易跟蹤和定位了。
4)使用私有堆使得大量?jì)却娴那謇碜兊梅奖?,在默認堆中分配的內存需要一塊塊單獨釋放,但將一個(gè)私有堆釋放后,在這個(gè)堆里的內存就全部被釋放掉了。并不需要預先釋放堆棧的每個(gè)內存塊。
 
私有堆的創(chuàng )建和釋放:
創(chuàng )建私有堆的函數是HeapCreate:
HANDLE WINAPI HeapCreate(
  __in  DWORD flOptions, //指定堆的屬性:
//HEAP_GENERATE_EXCEPTIONS---指定函數失敗時(shí)返回值,不指定這個(gè)標志時(shí),函數失敗
//時(shí)返回NULL、否則返回一個(gè)具體的錯誤代碼
         //HEAP_NO_SERIALIZE---控制對私有堆的訪(fǎng)問(wèn)是否要進(jìn)行獨占性的檢測;指定這個(gè)標志時(shí),
                            //建立堆時(shí)不進(jìn)行獨占性檢測,訪(fǎng)問(wèn)速度可以更快
  __in  SIZE_T dwInitialSize, //創(chuàng )建堆時(shí)分配給堆的物理內存(堆的內存不足時(shí)可以自動(dòng)擴展)
  __in  SIZE_T dwMaximumSize //能夠擴展到的最大物理內存
);
 
如果一個(gè)堆不再需要了,可以調用HeapDestroy函數將它釋放:
BOOL WINAPI HeapDestroy(
  __in  HANDLE hHeap //堆句柄
);
釋放私有堆可以釋放堆中包含的所有內存塊,也可以將堆占用的物理內存和保留的地址空間全部返還給系統。如果函數運行成功,返回值是TRUE;當在進(jìn)程終止時(shí)沒(méi)有調用HeapDestry函數將私有堆釋放時(shí),系統會(huì )自動(dòng)釋放。
 
 
在堆中分配和釋放內存塊:
如果要在堆中分配內存塊,可以使用HeapAlloc函數:
LPVOID WINAPI HeapAlloc(
  __in  HANDLE hHeap, //堆句柄
  __in  DWORD dwFlags, //以下標識的組合:HEAP_NO_SERIALIZE HEAP_GENERATE_EXCEPTIONS
                                     //HEAP_ZERO_MEMORY
  __in  SIZE_T dwBytes //需要分配的內存塊的字節數
);
注意,在堆中分配的內存塊只能是固定的內存塊,不想GlobalAlloc函數一樣可以分配可移動(dòng)的內存塊。
 
如果要釋放分配到的內存塊,可以使用HeapFree函數:
BOOL WINAPI HeapFree(
  __in  HANDLE hHeap, //堆句柄
  __in  DWORD dwFlags,
  __in  LPVOID lpMem //要釋放的內存塊指針,由HeapAlloc或HeapReAlloc返回
);
 
對于用HeapAlloc分配的內存塊,可以使用HeapReAlloc函數重新調整大?。?/div>
LPVOID WINAPI HeapReAlloc(
  __in  HANDLE hHeap, //堆句柄
  __in  DWORD dwFlags, //以下標識的組合:HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS
                                     //HEAP_ZERO_MEMORY | HEAP_REALLOC_IN_PLACE_ONLY
  __in  LPVOID lpMem, //內存塊指針
  __in  SIZE_T dwBytes //新的大小
);
 
其他堆管理函數:
1)GetProcessHeaps函數用來(lái)列出進(jìn)程中所有的堆:
DWORD WINAPI GetProcessHeaps(
  __in   DWORD NumberOfHeaps, //緩沖區中可以存放句柄的數量
  __out  PHANDLE ProcessHeaps //指向用來(lái)接收堆句柄的緩沖區的指針,緩沖區的長(cháng)度應該等于
                                               //NumberOfHeaps*4字節
);
函數執行后,進(jìn)程中所有堆的句柄全部返回到緩沖區中,其中也包括默認堆的句柄。
 
GetProcessHeap函數用來(lái)獲得進(jìn)程默認堆的句柄:
HANDLE WINAPI GetProcessHeap(void);
 
 
2)HeapWalk函數用來(lái)列出一個(gè)堆中所有內存塊:
BOOL WINAPI HeapWalk(
  __in     HANDLE hHeap, //堆句柄
  __inout  LPPROCESS_HEAP_ENTRY lpEntry //指向一個(gè)包含PROCESS_HEAP_ENTRY結構的緩沖區
);
調用HeapWalk函數時(shí),函數每次在PROCESS_HEAP_ENTRY結構中返回一個(gè)內存塊的信息,如果還有其他內存塊,函數返回TRUE,程序可以一直循環(huán)調用HeapWalk函數直到函數返回FALSE為止。在多線(xiàn)程程序中使用HeapWalk,必須首先使用HeapLock函數將堆鎖定,否則調用會(huì )失敗。
 
其中PROCESS_HEAP_ENTRY結構如下,它包含了堆元素的信息:
typedef struct _PROCESS_HEAP_ENTRY {
  PVOID lpData; //指向堆元素數據區的指針,初始調用HeapWalk時(shí),應將lpData設為NULL
  DWORD cbData; //堆元素數據區的字節大小
  BYTE  cbOverhead; //
  BYTE  iRegionIndex; //
  WORD  wFlags; //
  union {
    struct {
      HANDLE hMem; //
      DWORD  dwReserved[3]; //
    } Block;
    struct {
      DWORD  dwCommittedSize; //
      DWORD  dwUnCommittedSize; //
      LPVOID lpFirstBlock; //
      LPVOID lpLastBlock; //
    } Region;
  } ;
} PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY;
 
3)HeapValidate函數用來(lái)驗證堆的完整性或堆中某個(gè)內存塊的完整性:
BOOL WINAPI HeapValidate(
  __in      HANDLE hHeap, //要驗證的堆句柄
  __in      DWORD dwFlags, //標志位
  __in_opt  LPCVOID lpMem //為NULL,則函數順序驗證堆中所有的內存塊;
                                     //指定一個(gè)內存塊,則只驗證這個(gè)內存塊
);
如果驗證結果是內存塊都完好無(wú)損,函數返回非0值,否則函數返回0。
 
4)HeapLock和HeapUnlock函數用來(lái)鎖定和解鎖堆,這兩個(gè)函數用于線(xiàn)程的同步:
BOOL WINAPI HeapLock(
  __in  HANDLE hHeap
);
BOOL WINAPI HeapUnlock(
  __in  HANDLE hHeap
);
如果函數執行成功,返回值是非0值,否則返回0。一般來(lái)說(shuō),很少在程序中使用這兩個(gè)函數,而總是使用HEAP_NO_SERIALIZE標志來(lái)進(jìn)行同步控制,指定了這個(gè)標志的話(huà),HeapAlloc、HeapReAlloc、HeapSize和HeapFree等函數會(huì )在內部自己調用HeapLock和HeapUnlock函數。
 
5)HeapSize函數返回堆中某個(gè)內存塊的大小,這個(gè)大小就是使用HeapAlloc以及HeapReAlloc時(shí)指定的大?。?/div>
SIZE_T WINAPI HeapSize(
  __in  HANDLE hHeap, //堆句柄
  __in  DWORD dwFlags, //標志位
  __in  LPCVOID lpMem //需要返回大小的內存塊
);
 
6)HeapCompact函數用于合并堆中的空閑內存塊并釋放不在使用中的內存頁(yè)面:
SIZE_T WINAPI HeapCompact(
  __in  HANDLE hHeap,
  __in  DWORD dwFlags
);
 
下面實(shí)例代碼使用HeapWalk函數來(lái)遍歷一個(gè)堆:
 
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
 
int __cdecl _tmain()
{
    DWORD LastError;
    HANDLE hHeap;
    PROCESS_HEAP_ENTRY Entry;
 
    //
    // Create a new heap with default parameters.
    //
    hHeap = HeapCreate(0, 0, 0);
    if (hHeap == NULL) {
        _tprintf(TEXT("Failed to create a new heap with LastError %d.\n"),
                 GetLastError());
        return 1;
    }
 
    //
    // Lock the heap to prevent other threads from accessing the heap
    // during enumeration.
    //
    if (HeapLock(hHeap) == FALSE) {
        _tprintf(TEXT("Failed to lock heap with LastError %d.\n"),
                 GetLastError());
        return 1;
    }
 
    _tprintf(TEXT("Walking heap %#p...\n\n"), hHeap);
 
    Entry.lpData = NULL;
    while (HeapWalk(hHeap, &Entry) != FALSE) {
        if ((Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
            _tprintf(TEXT("Allocated block"));
 
            if ((Entry.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) != 0) {
                _tprintf(TEXT(", movable with HANDLE %#p"), Entry.Block.hMem);
            }
 
            if ((Entry.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) != 0) {
                _tprintf(TEXT(", DDESHARE"));
            }
        }
        else if ((Entry.wFlags & PROCESS_HEAP_REGION) != 0) {
            _tprintf(TEXT("Region\n  %d bytes committed\n") \
                     TEXT("  %d bytes uncommitted\n  First block address: %#p\n") \
                     TEXT("  Last block address: %#p\n"),
                     Entry.Region.dwCommittedSize,
                     Entry.Region.dwUnCommittedSize,
                     Entry.Region.lpFirstBlock,
                     Entry.Region.lpLastBlock);
        }
        else if ((Entry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) != 0) {
            _tprintf(TEXT("Uncommitted range\n"));
        }
        else {
            _tprintf(TEXT("Block\n"));
        }
 
        _tprintf(TEXT("  Data portion begins at: %#p\n  Size: %d bytes\n") \
                 TEXT("  Overhead: %d bytes\n  Region index: %d\n\n"),
                 Entry.lpData,
                 Entry.cbData,
                 Entry.cbOverhead,
                 Entry.iRegionIndex);
    }
    LastError = GetLastError();
    if (LastError != ERROR_NO_MORE_ITEMS) {
        _tprintf(TEXT("HeapWalk failed with LastError %d.\n"), LastError);
    }
 
    //
    // Unlock the heap to allow other threads to access the heap after
    // enumeration has completed.
    //
    if (HeapUnlock(hHeap) == FALSE) {
        _tprintf(TEXT("Failed to unlock heap with LastError %d.\n"),
                 GetLastError());
    }
 
    //
    // When a process terminates, allocated memory is reclaimed by the operating
    // system so it is not really necessary to call HeapDestroy in this example.
    // However, it may be advisable to call HeapDestroy in a longer running
    // application.
    //
    if (HeapDestroy(hHeap) == FALSE) {
        _tprintf(TEXT("Failed to destroy heap with LastError %d.\n"),
                 GetLastError());
    }
 
    return 0;
}
 
下面的實(shí)例代碼使用GetProcessHeaps函數獲得進(jìn)程中所有堆的句柄:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <intsafe.h>
 
int __cdecl _tmain()
{
    DWORD NumberOfHeaps;
    DWORD HeapsIndex;
    DWORD HeapsLength;
    HANDLE hDefaultProcessHeap;
    HRESULT Result;
    PHANDLE aHeaps;
    SIZE_T BytesToAllocate;
 
    //
    // Retrieve the number of active heaps for the current process
    // so we can calculate the buffer size needed for the heap handles.
    //
    NumberOfHeaps = GetProcessHeaps(0, NULL);
    if (NumberOfHeaps == 0) {
        _tprintf(TEXT("Failed to retrieve the number of heaps with LastError %d.\n"),
                 GetLastError());
        return 1;
    }
 
    //
    // Calculate the buffer size.
    //
    Result = SIZETMult(NumberOfHeaps, sizeof(*aHeaps), &BytesToAllocate);
    if (Result != S_OK) {
        _tprintf(TEXT("SIZETMult failed with HR %d.\n"), Result);
        return 1;
    }
 
    //
    // Get a handle to the default process heap.
    //
    hDefaultProcessHeap = GetProcessHeap();
    if (hDefaultProcessHeap == NULL) {
        _tprintf(TEXT("Failed to retrieve the default process heap with LastError %d.\n"),
                 GetLastError());
        return 1;
    }
 
    //
    // Allocate the buffer from the default process heap.
    //
    aHeaps = (PHANDLE)HeapAlloc(hDefaultProcessHeap, 0, BytesToAllocate);
    if (aHeaps == NULL) {
        _tprintf(TEXT("HeapAlloc failed to allocate %d bytes.\n"),
                 BytesToAllocate);
        return 1;
    }
 
    //
    // Save the original number of heaps because we are going to compare it
    // to the return value of the next GetProcessHeaps call.
    //
    HeapsLength = NumberOfHeaps;
 
    //
    // Retrieve handles to the process heaps and print them to stdout.
    // Note that heap functions should be called only on the default heap of the process
    // or on private heaps that your component creates by calling HeapCreate.
    //
    NumberOfHeaps = GetProcessHeaps(HeapsLength, aHeaps);
    if (NumberOfHeaps == 0) {
        _tprintf(TEXT("Failed to retrieve heaps with LastError %d.\n"),
                 GetLastError());
        return 1;
    }
    else if (NumberOfHeaps > HeapsLength) {
 
        //
        // Compare the latest number of heaps with the original number of heaps.
        // If the latest number is larger than the original number, another
        // component has created a new heap and the buffer is too small.
        //
        _tprintf(TEXT("Another component created a heap between calls. ") \
                 TEXT("Please try again.\n"));
        return 1;
    }
 
    _tprintf(TEXT("Process has %d heaps.\n"), HeapsLength);
    for (HeapsIndex = 0; HeapsIndex < HeapsLength; ++HeapsIndex) {
        _tprintf(TEXT("Heap %d at address: %#p.\n"),
                 HeapsIndex,
                 aHeaps[HeapsIndex]);
    }
 
    //
    // Release memory allocated from default process heap.
    //
    if (HeapFree(hDefaultProcessHeap, 0, aHeaps) == FALSE) {
        _tprintf(TEXT("Failed to free allocation from default process heap.\n"));
    }
 
    return 0;
}
 
#include "stdafx.h"
#include <windows.h>
#include <iostream.h>

int main(int argc, char* argv[])
{
 //創(chuàng )建堆
 HANDLE hHeap = HeapCreate(
  HEAP_GENERATE_EXCEPTIONS, //排除例外
  10 << 10,     //起始于10K
  10 << 20);     //終止于10K
 if(hHeap != NULL)
 {
  //分配大的塊
  LPVOID pLarge = HeapAlloc(
   hHeap,
   HEAP_ZERO_MEMORY,
   1024);
  //分配小的塊
  LPVOID pSmall = HeapAlloc(
   hHeap,
   HEAP_ZERO_MEMORY,
   1);
  PROCESS_HEAP_ENTRY phe;
  ZeroMemory(&phe, sizeof(phe));
  HeapLock(hHeap);
  while(HeapWalk(hHeap, &phe))
  {
   if(phe.lpData == pLarge)
   {
    cout<<"Found large block"<<endl;
   }
   else if(phe.lpData == pSmall)
   {
    cout<<"Found small block"<<endl;
   }
   else
   {
    cout<<"Anonymous block"<<endl;
   }
  }
  HeapUnlock(hHeap);
  HeapFree(hHeap, 0, pLarge);
  pLarge = NULL;
  HeapFree(hHeap, 0, pSmall);
  pSmall = NULL;
 }
 return 0;
}
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久