動的メモリ管理

スポンサーリンク

次のプログラムは,動的に (実行時に) サイズを指定してメモリ領域を用意するプログラムの例です。
実行時まで長さがわからない配列を扱う際などに,このような手法を使うことになります。

#include <stdio.h>
#include <stdlib.h>  /* malloc, free 関数のため */

int main(void)
{
    int size = 5;
    int *arr;

    arr = (int *) malloc(size * sizeof(int));  /* メモリを動的に確保 */

    /* メモリ領域を使用... */

    free(arr);   /* メモリを解放 */

    return 0;
}

malloc 関数

動的に (実行時に) メモリ領域を確保するには,関数 malloc (memory allocate) を使います。
引数は確保すべきバイト数,返り値は確保されたメモリ領域へのポインタです (失敗時 NULL)。

arr = (int *) malloc(size * sizeof(int)) は,宣言 int arr[size] におおよそ相当します。
malloc 関数の返却型が void * (汎用ポインタ) なので,具体的なポインタ型にキャストするのがベターです (型チェックの厳しい C++ ではキャストがないとエラーが出ます)。

void *malloc(size_t size);

free 関数

malloc 関数で動的に確保したメモリ領域は,必ず free 関数で解放します。

void free(void *ptr);

解放されないメモリ領域は,ゾンビのように生き続け,メモリを占有し続けます。
長時間プログラムを走らせていると,些細なメモリ領域の解放し忘れが無数に重なり,やがてメモリを食いつぶします。
このようなメモリの解放漏れのことをメモリリーク (memory leak) と呼びます.

malloc 関数のバリアント

動的にメモリを確保するために使える関数には,malloc 以外にもいくつかの種類があります。

関数名 関数プロトタイプ 説明 ゼロクリア
malloc void *malloc(size_t size); 指定したバイト数 (size バイト) の領域を確保します。 されない
calloc void *calloc(size_t n, size_t size); 指定したバイト数 (n * size バイト) の領域を確保します。 される
realloc void *realloc(void *ptr, size_t size); 確保済みの領域を指定したバイト数で再確保します。 されない

calloc 関数は,malloc 関数と同様に指定したバイト数の領域を動的に確保する関数です。
働きは malloc 関数とほぼ同じですが,確保された領域がゼロクリアされる (0 で初期化される) 点が違います。

realloc 関数は,malloc/calloc/realloc 関数で確保済みの領域を指定したバイト数で確保し直します。
第 1 引数には,確保済みメモリ領域へのポインタを指定します。

スポンサーリンク