本文へスキップ
BecomeCoder

C言語コース · 第8章 動的メモリ管理 · レッスン31

malloc/free ― ヒープから借りて、自分で返す

ブラウザで完結

導入

配列の個数を、実行中に決めたい」ことがあります。C言語には、実行中に必要な分だけメモリヒープから確保する malloc と、使い終わったらそれを返す free があります。この2つは必ず対で使います。

説明

malloc(バイト数) はヒープにメモリを確保し、その先頭アドレス(void*)を返します。確保できなかった場合は NULL を返すので、必ずチェックします。sizeof を使うと「型のバイト数」を安全に計算できます。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n = 5;
    int *arr = malloc(n * sizeof(int));   // int が n個分入る領域を確保
    if (arr == NULL) {                    // 確保に失敗したら NULL が返る
        printf("確保失敗\n");
        return 1;
    }

    int i;
    for (i = 0; i < n; i++) {
        arr[i] = (i + 1) * 10;
    }

    int sum = 0;
    for (i = 0; i < n; i++) {
        sum += arr[i];
    }
    printf("合計=%d\n", sum);

    free(arr);   // 使い終わったら必ず返す
    return 0;
}

arr はふつうのポインタなので、arr[i] のように配列と同じ書き方でアクセスできます。違うのは「個数を実行中に決めた」ことと、「使い終わったら自分で free する」ことです。

flowchart LR
  a["malloc(n * sizeof(int))<br/>ヒープに確保"] --> b["arr[i] で読み書き"]
  b --> c["free(arr)<br/>使い終わったら返す"]
  a -.->|"NULLが返ることもある"| x["確保失敗(必ずチェック)"]

やってみよう

n の値を変えて、確保する個数が変わることを確かめましょう。free(arr); の行を一時的に消してみても、この程度の実行では出力は変わりません(この「消し忘れても気づかない」ことが、次のレッスン34で扱う問題そのものです)。

演習

n10 にして、arr[i]1 から 10 までの値(i + 1)を入れ、合計を printf("合計=%d\n", sum); の形で表示してください(正しく書けると 合計=55 になります)。最後に free で解放してください。

ヒント1を見る

int n = 10; に変え、arr[i] = i + 1; で埋めます。

ヒント2を見る

sum0 から初めて、ループsum += arr[i]; を足します。

実際に動かしてみよう

下のエディタにCを書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のCコンパイラ(clang + dlmalloc)がその場でコンパイルして実行し、出力が表示されます。構造体・共用体・malloc/free・関数ポインタ・ファイル入出力などがそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(scanf)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。