メモリ確保の失敗を確認する
CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 34/63。
malloc() は動的メモリ割り当てのための強力なツールですが、理解しておくべき重要な事実があります。それは、malloc() は失敗する可能性があるということです。システムの空きメモリがなくなると、malloc() はリクエストを処理できず、有効なメモリアドレスの代わりに NULL を返します。
これは、malloc() を使用するたびに、返されたポインタを使用しようとする前に、それが成功したかどうかを確認しなければならないことを意味します。NULL ポインタを使用すると、プログラムがセグメンテーションフォールトでクラッシュする原因となります。
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // プログラムを終了するか、エラーを処理します
}
// ここで ptr を安全に使用できます
*ptr = 42;このNULLチェックは任意ではありません。堅牢なCプログラムを書くためには不可欠です。現代のシステムではメモリ割り当ての失敗は稀ですが、特にリソースが制限された環境や大量のメモリを要求する場合には発生する可能性があります。プロフェッショナルなCコードには、クラッシュを防ぎ、適切なエラー処理を行うために、常にこれらのチェックが含まれています。
チャレンジ
簡単動的メモリ割り当てに malloc() を使用する際の、適切なエラーハンドリングを実演するC言語プログラムを作成してください。プログラムは以下の手順に従う必要があります:
- 格納する整数の数を示す整数
nをユーザーから読み取ります sizeof()とmalloc()を使用して、n個の整数の配列のためのメモリを動的に割り当てます- 返されたポインタが
NULLかどうかをテストして、メモリ割り当てが成功したか確認します - 割り当てに失敗した場合は、
Memory allocation failed!と出力してプログラムを終了します - 割り当てに成功した場合は、
Memory allocation successful!と出力します - ユーザーから
n個の整数値を読み取り、割り当てられた配列に格納します - すべての値の合計を計算し、
Sum: [value]の形式で出力します - 割り当てられた合計バイト数を
Bytes allocated: [value]の形式で出力します
malloc() を使用するために <stdlib.h> ヘッダーを含めることを忘れないでください。プログラムは、割り当てられたメモリを使用しようとする前に、割り当ての失敗をチェックするという不可欠な慣行を示す必要があります。
例えば、入力が以下の場合:
4
10 20 30 40出力は以下のようになります:
Memory allocation successful!
Sum: 100
Bytes allocated: 16このチャレンジでは、動的メモリ割り当てを扱う際の防御的プログラミングの重要性を強調しています。これにより、プログラムが予期せずクラッシュするのではなく、潜在的なメモリ割り当ての失敗を適切に処理できるようになります。
チートシート
割り当てられたメモリを使用する前に、malloc() が NULL を返しているか必ず確認してください:
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // プログラムを終了するか、エラーを処理します
}
// ここで ptr を安全に使用できます
*ptr = 42;malloc() は、システムの空きメモリが不足すると失敗することがあります。NULL ポインタを使用すると、セグメンテーション違反(segmentation fault)が発生します。この NULL チェックは、堅牢な C プログラムを記述し、クラッシュを防ぐために不可欠です。
自分で試してみよう
#include <stdio.h>
#include <stdlib.h>
int main() {
// 整数の数を読み込む
int n;
scanf("%d", &n);
// TODO: ここにコードを記述してください
// - malloc() を使用して n 個の整数用のメモリを割り当てる
// - メモリ割り当てが成功したか確認する
// - 成功と失敗の両方のケースを処理する
// - 整数を読み込んで保存する
// - 合計と割り当てられたバイト数を計算する
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。