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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- malloc と free
- calloc と realloc
- メモリリーク
- ダングリングポインター