メモリ割り当て

ヒープ (heap)

ヒープ領域にメモリブロックを割り当て、そのアドレスを取得できます。

void *malloc(
   size_t size // 割り当てるバイト数
);
malloc | MSDN

アラインメントとメインテナンス情報にメモリが必要なため、sizeを超える領域が確保されることがあります。

メモリが不足しNULLが返されるときには、不要になった領域を開放し忘れていないか確認します。

32ビットのコンパイラで2GBを超える領域を確保するには、/LARGEADDRESSAWAREリンカーオプションを指定します。 これにより4GBまで利用できるようになります。 -LARGEADDRESSAWARE (Handle Large Addresses) | Microsoft Learn Memory Limits for Windows and Windows Server Releases | Microsoft Learn

calloc()

intやlongなどのビット長が環境依存の型に対しては、calloc()を用います。

void *calloc(
   size_t num, // 要素の数
   size_t size // 各要素のバイト数
);
calloc | MSDN
関数 確保されるバイト数 初期値
malloc sizeバイト以上 未定義
calloc num × sizeバイト以上 0
int* p1 = (int*)malloc(10);
// つねに10バイト以上が確保される

int* p2 = (int*)calloc(10, sizeof(int));
// sizeof(int)が4(32ビット)ならば40バイト、8(64ビット)ならば80バイト以上が確保される

割り当ての開放

void free(
   void *memblock // 解放するメモリブロックへのポインタ
);
free | MSDN

割り当てたメモリブロックは、不要になった時点で必ず解放します。

char* p = (char*)malloc(10);
if (p == NULL)
{
    // メモリ不足
}
else
{
    // ...

    free(p);
}

割り当てサイズの変更

void *realloc(
   void *memblock, // すでに割り当てられているメモリブロックへのポインタ
   size_t size     // 新しく割り当てるバイト数
);
realloc | MSDN

すでに割り当てられている領域のサイズを変更できます。変更後のメモリへのポインタは変更前と同じである保証がないため、新しいポインタを用います。

メモリリークの検出

CRTのデバッグ ヒープ関数が有効ならば、領域を越えてアクセスしたときに次のように警告されます。

HEAP CORRUPTION DETECTED: after Normal block (#***) at 0x***.
CRT detected that the application wrote to memory after end of heap buffer.

スタック (stack)

後入れ先出し (LIFO) のスタック領域に、メモリブロックを割り当てられます。

void *_alloca(
   size_t size
);
_alloca | MSDN
void *_malloca(
   size_t size
);
_malloca | MSDN
関数 割り当て場所 メモリの解放
_alloca スタック 明示的に解放できず、自動で解放される。
_malloca スタック (ただし_ALLOCA_S_THRESHOLDを越える場合はヒープ) _freea()で解放しなければならない。

いずれも領域が割り当てられなかった場合は、スタックオーバーフロー例外が発生します。

c - Why is the use of alloca() not considered good practice? - Stack Overflow

メモリ割り当ての既定値

確保された領域には決められた値が書き込まれることがあり、デバッグの参考になります。

意味
0xABABABAB Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory
0xABADCAFE A startup to this value to initialize all free memory to catch errant pointers
0xBAADF00D Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialized allocated heap memory
0xBADCAB1E Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger
0xBEEFCACE Used by Microsoft .NET as a magic number in resource files
0xCCCCCCCC Used by Microsoft's C++ debugging runtime library to mark uninitialized stack memory
0xCDCDCDCD Used by Microsoft's C++ debugging runtime library to mark uninitialized heap memory
0xDDDDDDDD Used by Microsoft's C++ debugging heap to mark freed heap memory
0xDEADDEAD A Microsoft Windows STOP Error code used when the user manually initiates the crash.
0xFDFDFDFD Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory
0xFEEEFEEE Used by Microsoft's HeapFree() to mark freed heap memory

割り当て可能なメモリの上限

Windowsでの仮想アドレス空間の上限
  32bit Windows 64bit Windows
32bit プロセス
  • [既定] … 2GB
  • 大きいサイズのアドレス※14GTが有効 … 3GB
  • 大きいサイズのアドレスが無効 [既定] … 2GB
  • 大きいサイズのアドレスが有効 … 4GB
64bit プロセス ---
  • 大きいサイズのアドレスが無効 … 2GB
  • 大きいサイズのアドレスが有効 [既定]
    • x64 … 8TB
    • Intel Itanium … 7TB
    • Windows 8.1とWindows Server 2012 R2 … 128TB
Memory Limits for Windows and Windows Server Releases | Microsoft Learn ※1 リンカオプションの/LARGEADDRESSAWAREでIMAGE_FILE_LARGE_ADDRESS_AWAREが設定された状態

参考

参考書

Microsoft Learnから検索