free() によるメモリの解放
CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 35/63。
malloc() を使用してメモリを動的に割り当てると、そのメモリは明示的に解放するまで割り当てられたままになります。free() 関数は、動的に割り当てられたメモリの使用が終わったときに、そのメモリをシステムに返却するためのツールです。
free()関数は、解放したいメモリブロックへのポインタという1つの引数を取ります。これは、malloc()(またはcalloc()のような関連関数)によって返されたものと同じポインタである必要があります。
#include <stdlib.h>
int *ptr = (int*)malloc(sizeof(int)); // メモリを割り当てる
*ptr = 42; // メモリを使用する
free(ptr); // 完了したらメモリを解放するfree() の呼び出しを忘れると、メモリリークと呼ばれる状態が発生します。割り当てられたメモリは、もはや使用されていないにもかかわらず、プログラムによって予約されたままになります。長時間実行されるプログラムや、繰り返しメモリを割り当てるプログラムでは、これらのリークが利用可能なすべてのシステムメモリを消費し、パフォーマンスの問題やクラッシュを引き起こす可能性があります。
覚えておいてください:すべての malloc() には、対応する free() が必要です。このペアリングは、Cプログラミングにおける責任あるメモリ管理に不可欠です。
チャレンジ
簡単動的メモリの割り当てと解放の完全なライフサイクルを実証するCプログラムを作成してください。プログラムは以下の手順で行う必要があります:
- 格納する整数の数を示す整数
countをユーザーから読み取ります malloc()とsizeof()を使用して、count個の整数を格納するための配列にメモリを動的に割り当てます- メモリ割り当てが成功したか確認します。失敗した場合は、
Memory allocation failed!と出力してプログラムを終了します - 割り当てに成功した場合は、
Memory allocated successfully!と出力します - ユーザーから
count個の整数値を読み取り、割り当てられた配列に格納します - すべての値の合計を
Sum: [value]の形式で計算して出力します - 最大値を
Maximum: [value]の形式で検索して出力します free()を使用してメモリを解放します- クリーンアップを確認するために
Memory freed successfully!と出力します
malloc() と free() を使用するために、<stdlib.h> ヘッダーをインクルードすることを忘れないでください。このチャレンジは、プログラム内でのメモリリークを防ぐための malloc() と free() の不可欠なペアリングを実証するものです。
例えば、入力が以下の場合:
4
15 8 23 12出力は以下のようになります:
Memory allocated successfully!
Sum: 58
Maximum: 23
Memory freed successfully!このチャレンジは、動的に割り当てられたすべてのメモリブロックは、不要になったときに適切に解放されなければならないという重要な概念を強化し、Cプログラミングにおける責任あるメモリ管理サイクルを完結させます。
チートシート
malloc() で割り当てられたメモリを解放するには、free() を使用します:
#include <stdlib.h>
int *ptr = (int*)malloc(sizeof(int)); // メモリを割り当てる
*ptr = 42; // メモリを使用する
free(ptr); // 完了したらメモリを解放するメモリリークを防ぐために、すべての malloc() には対応する free() が必要です。free() に渡されるポインタは、malloc() によって返されたものと同じポインタである必要があります。
自分で試してみよう
#include <stdio.h>
#include <stdlib.h>
int main() {
int count;
// 格納する整数の数を読み取る
scanf("%d", &count);
// TODO: 以下にコードを記述してください
// 1. sizeof() を使用して malloc() でメモリを割り当てる
// 2. 割り当てが成功したか確認する
// 3. 整数値を読み取って格納する
// 4. 合計を計算し、最大値を見つける
// 5. 割り当てられたメモリを解放する
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。