メモリを動的に確保する方法【Windows API】

構造体や配列のサイズを動的に確保する場合、CやC++では可変長配列が無いため このような処理を実装する場合は動的にメモリを確保する必要がある。 memset関数等を使用して実装するケースが多いが今回はAPIを使ってメモリ確保を行う。 GlobalAlloc関数については以前にクリップボードの処理で取り扱ったものと同じである。 HeapAlloc関数の方が高速に処理できるので、できる限りそちらを使用するべきである。 当然ながら自動的に開放されることはありませんので、かならず開放処理を書いてください。

#include <windows.h>

int main(int argc, char* argv[])
{
    HGLOBAL hGMem;
    DWORD dwSize;

    // ----------------------------------------------------
    //    固定メモリで確保した場合
    // ----------------------------------------------------

    // メモリを確保する(GMEM_FIXED:固定メモリで確保)
    // GMEM_ZEROINITを指定するとゼロクリア処理まで勝手に行なってくれる
    // 取得したハンドルはそのままポインタとして使用できる
    hGMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(char) * 10);

    dwSize = GlobalSize(hGMem);
    lstrcpy((char*)hGMem, "ABCDEFG");

    printf("Buffer Size=[%d] , Data=[%s]\n", dwSize, (char*)hGMem);

    // メモリを拡張する
    hGMem = GlobalReAlloc(hGMem, sizeof(char) * 20, GMEM_MOVEABLE);

    dwSize = GlobalSize(hGMem);
    lstrcat((char*)hGMem, "0123456789");

    printf("Buffer Size=[%d] , Data=[%s]\n", dwSize, (char*)hGMem);

    // 確保したメモリを開放する
    GlobalFree(hGMem);

    // ----------------------------------------------------
    //    移動可能メモリで確保した場合
    // ----------------------------------------------------

    // 移動可能メモリで確保する
    hGMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(char) * 10);

    // メモリの位置をロックする
    // ハンドルからポインタに変換する
    char *pszBuff = (char*)GlobalLock(hGMem);

    // 確保したメモリを使用する
    lstrcpy(pszBuff, "ZZZ");
    printf("[%s]\n", pszBuff);

    // メモリのロックを解除する
    GlobalUnlock(hGMem);

    // メモリを開放する
    GlobalFree(hGMem);

    return 0;
}

 

Windows API

Posted by @erestage