calloc() によるメモリ確保
CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 36/63。
malloc() は動的メモリ割り当てにおいて最も一般的な関数ですが、C言語にはもう一つの便利な代替手段として calloc() が用意されています。calloc() 関数(「contiguous allocation(連続割り当て)」の略)は、配列用のメモリを割り当てるための便利な方法を提供し、さらに重要な利点も備えています。
単一の引数(合計バイト数)を受け取る malloc() とは異なり、calloc() は2つの引数(割り当てたい要素の数と、各要素のサイズ)を受け取ります。これにより、配列を扱う際に特に直感的になります。例えば:
#include <stdlib.h>
// calloc() を使用して5つの整数用のスペースを割り当てる
int *arr = (int*)calloc(5, sizeof(int));
// これは malloc(5 * sizeof(int)) と同等ですcalloc() の主な利点は、割り当てられたすべてのメモリを自動的にゼロに初期化することです。malloc() を使用すると、割り当てられたメモリには以前に格納されていたランダムな値が含まれますが、calloc() はすべてのバイトがゼロに設定されることを保証します。これは、すべての整数が 0、すべての浮動小数点数が 0.0、そしてすべてのポインタが NULL になることを意味します。
malloc() と同様に、calloc() は割り当てられたメモリへのポインタを返します。割り当てに失敗した場合は NULL を返します。そのため、常に割り当ての失敗をチェックし、使い終わったら free() でメモリを解放することを忘れないようにしてください。
チャレンジ
簡単動的メモリ割り当てと自動ゼロ初期化を行う calloc() の使用方法を示すCプログラムを作成してください。プログラムは以下の手順に従う必要があります:
- ユーザーから割り当てる整数の数を表す整数
sizeを読み取ります calloc()を使用して、size個の整数の配列用にメモリを動的に割り当てます- メモリ割り当てが成功したか確認します。失敗した場合は、
Memory allocation failed!と出力してプログラムを終了します - 割り当てに成功した場合は、
Memory allocated and initialized to zero!と出力します - 配列内のすべての初期値がゼロであることを示すために、次の形式で出力します:
Initial values: [value1] [value2] [value3] ... - ユーザーから
size個の整数値を読み取り、割り当てられた配列に格納します - 更新されたすべての値を次の形式で出力します:
Updated values: [value1] [value2] [value3] ... - すべての値の合計を計算し、次の形式で出力します:
Sum: [value] free()を使用してメモリを解放します- クリーンアップを確認するために
Memory freed!と出力します
calloc() と free() を使用するために、<stdlib.h> ヘッダーをインクルードすることを忘れないでください。この課題は、malloc() に対する calloc() の主な利点である、割り当てられたすべてのメモリを自動的にゼロに初期化することを示しています。
例えば、入力が以下の場合:
3
10 20 30出力は以下のようになります:
Memory allocated and initialized to zero!
Initial values: 0 0 0
Updated values: 10 20 30
Sum: 60
Memory freed!この課題は、calloc() が動的に割り当てられた配列に対して、クリーンで予測可能な初期状態をどのように提供し、malloc() が残す可能性のある予測不可能なガベージ値をどのように排除するかを強調しています。
チートシート
calloc() 関数は、自動的なゼロ初期化を伴う動的メモリ割り当てを提供します。
構文:
void* calloc(size_t num_elements, size_t element_size);malloc() との主な違い:
- 2つの引数を取ります:要素数と各要素のサイズ
- 割り当てられたすべてのメモリを自動的にゼロに初期化します
- 配列の割り当てに対してより直感的です
使用例:
#include <stdlib.h>
// calloc() を使用して5つの整数用のスペースを割り当てます
int *arr = (int*)calloc(5, sizeof(int));
// これは malloc(5 * sizeof(int)) と同等です
// しかし、すべての値が0であることが保証されますmalloc() と同様に、calloc() は割り当てられたメモリへのポインタを返します。割り当てに失敗した場合は NULL を返します。常に割り当ての失敗を確認し、完了したら free() を使用してメモリを解放してください。
自分で試してみよう
#include <stdio.h>
#include <stdlib.h>
int main() {
int size;
// 配列のサイズを読み込む
scanf("%d", &size);
// TODO: 以下にコードを記述してください
// calloc() を使用して配列のメモリを割り当てる
// メモリ割り当てが成功したか確認する
// 初期値を表示する(0であるはず)
// 入力値を読み込んで保存する
// 更新された値を表示する
// 合計を計算して表示する
// 割り当てられたメモリを解放する
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。