0Pricing
C Academy · レッスン

malloc と free

ヒープにメモリを確保します。

「malloc と free」はCoddyKit上の無料C Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。

ヒープ

これまで、変数はスタック上に置かれ、存続期間は固定されていました。ヒープを使うと、実行時にメモリを要求し、必要な期間だけ保持できます。

ヒープメモリは、<stdlib.h>の関数を使って自分で管理します。

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

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 99;
    printf("%d\n", *p);
    free(p);
    return 0;
}

mallocを呼び出す

malloc(size)はsizeバイトを確保し、その領域へのポインターを返します。失敗した場合はNULLを返します。

メモリは未初期化であり、内容は不定です。

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

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 7;
    printf("value = %d\n", *p);
    free(p);
    return 0;
}

sizeofでサイズを指定する

どのプラットフォームでも正しく動作するように、確保するサイズは必ずsizeofで指定します。

sizeof(*p)と記述すると、サイズがポインターの型に自動的に対応します。

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

int main(void) {
    double *p = malloc(sizeof(*p));
    *p = 3.14;
    printf("%f\n", *p);
    free(p);
    return 0;
}

必ずNULLを確認する

メモリ確保に失敗すると、mallocはNULLを返します。これをデリファレンスするとプログラムがクラッシュします。

使用する前に結果を確認してください。

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

int main(void) {
    int *p = malloc(sizeof(int));
    if (p == NULL) {
        printf("allocation failed\n");
        return 1;
    }
    *p = 5;
    printf("ok: %d\n", *p);
    free(p);
    return 0;
}

配列を確保する

多数の要素を格納するには、要素のサイズに個数を掛けます。

malloc(n * sizeof(int))でn個の整数を格納できる領域を作成します。

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

int main(void) {
    int n = 5;
    int *arr = malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) arr[i] = i * i;
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    free(arr);
    return 0;
}

ヒープ配列ではポインターによるインデックス指定を使う

ヒープ配列には、通常のarr[i]構文でポインターを介してアクセスできます。これは*(arr + i)と同じです。

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

int main(void) {
    int *arr = malloc(3 * sizeof(int));
    arr[0] = 10;
    *(arr + 1) = 20;
    arr[2] = 30;
    printf("%d %d %d\n", arr[0], arr[1], arr[2]);
    free(arr);
    return 0;
}

メモリを解放する

free(p)は、そのブロックをアロケーターに返します。この後、pを使ってそのメモリにアクセスしてはいけません。

成功したすべてのmallocには、対応するfreeが必要です。

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

int main(void) {
    char *buf = malloc(16);
    if (buf) {
        buf[0] = 'A';
        printf("%c\n", buf[0]);
        free(buf);
    }
    return 0;
}

free(NULL)は安全

NULLポインターに対してfreeを呼び出しても何も起こらず、完全に合法です。

これにより、メモリ確保に成功する前に実行される可能性があるクリーンアップコードを簡潔にできます。

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

int main(void) {
    int *p = NULL;
    free(p);
    printf("free(NULL) was safe\n");
    return 0;
}

ヒープメモリを返す

スタック変数とは異なり、ヒープメモリは関数が返った後も存続します。そのため、関数でバッファーを確保して返すことができます。

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

int *make_range(int n) {
    int *a = malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) a[i] = i;
    return a;
}

int main(void) {
    int *r = make_range(4);
    printf("%d %d\n", r[0], r[3]);
    free(r);
    return 0;
}

Cではmallocをキャストしない

Cでは、mallocはvoid *を返し、それは任意のポインター型に自動的に変換されます。

キャストは不要であり、<stdlib.h>のインクルード漏れを隠してしまう可能性があります。

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

int main(void) {
    long *p = malloc(sizeof(long));
    *p = 1234567L;
    printf("%ld\n", *p);
    free(p);
    return 0;
}

二重解放をしない

同じポインターに対してfreeを2回呼び出すと未定義動作になり、ヒープが破壊される可能性があります。

解放後にポインターをNULLに設定すると、誤った再利用を安全に防げます。

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

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 1;
    free(p);
    p = NULL;
    free(p);
    printf("no double free\n");
    return 0;
}

理解度チェック

mallocとfreeについての知識を確認しましょう。

まとめ

ヒープ確保の基本を学びました。

  • malloc(size)は未初期化のバイト領域を確保し、失敗時にはNULLを返します。
  • 結果を必ず確認し、サイズにはsizeofを使用します。
  • free(p)でメモリを返します。すべてのmallocには1回のfreeが必要です。
  • free(NULL)は安全ですが、二重解放は未定義動作です。

よくある質問

「malloc と free」レッスンは無料ですか?

はい。「malloc と free」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。

「malloc と free」で何を学びますか?

ヒープにメモリを確保します。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「malloc と free」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC Academyレッスンでコードを書いて実行できますか?

はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. malloc と free
  2. calloc と realloc
  3. メモリリーク
  4. ダングリングポインター
← C Academyに戻る