メモリ確保での sizeof() の使用
CoddyのCジャーニー「Logic & Flow」セクションの一部 — レッスン 33/63。
malloc() を使用するとメモリを動的に割り当てることができますが、コードの移植性とメンテナンス性を高めるための重要なベストプラクティスがあります。それは、割り当てるバイト数を決定するために sizeof() 演算子を使用することです。
sizeof() 演算子は、システム上で特定のデータ型を格納するために必要なバイト数を返します。バイト数をハードコーディングする代わりに、sizeof() に正しい量を自動的に計算させることができます:
// バイトサイズを推測する代わりに:
int *ptr = (int*)malloc(4); // intが4バイトであると仮定しています
// 移植性のためにsizeof()を使用します:
int *ptr = (int*)malloc(sizeof(int)); // 常に正解ですこのアプローチは、配列を割り当てる際に特に価値があります。複数の要素にスペースを割り当てるには、要素の数に各要素のサイズを掛けます:
// 10個の整数用のメモリを確保する
int *arr = (int*)malloc(10 * sizeof(int));
// 5個のdouble型用のメモリを確保する
double *values = (double*)malloc(5 * sizeof(double));sizeof() を使用することで、データ型のサイズが異なる可能性があるさまざまなシステム間でコードが正しく動作するようになります。また、特定の型の特定の要素数のためにスペースを割り当てるという意図を明確に伝えることができます。
チャレンジ
簡単動的メモリ割り当てのために malloc() と sizeof() を適切に使用する方法を示すC言語プログラムを作成してください。プログラムは以下の処理を行う必要があります:
- 割り当てる要素数を表す整数
nをユーザーから読み込む sizeof()とmalloc()を使用して、n個の double 型の値を格納するためのメモリを動的に割り当てる- 返された void ポインタを double ポインタにキャストする
- ユーザーから
n個の double 型の値を読み込み、割り当てられた配列に格納する - 割り当てられた合計メモリ(バイト単位)を計算し、次の形式で出力する:
Memory allocated: [bytes] bytes - すべての値の平均を計算し、小数点以下2桁で次の形式で出力する:
Average: [value] - 最大値を見つけ、小数点以下2桁で次の形式で出力する:
Largest: [value]
malloc() を使用するために <stdlib.h> ヘッダーをインクルードすることを忘れないでください。このプログラムは、システムのデータ型のサイズに関わらず、sizeof() がどのように正しいメモリ割り当てを保証するかを示す必要があります。
例えば、入力が以下の場合:
3
2.5 7.8 4.1出力は以下のようになります:
Memory allocated: 24 bytes
Average: 4.80
Largest: 7.80このチャレンジは、動的メモリ割り当てをポータブルでメンテナンスしやすくするために sizeof() を使用することの重要性を再確認するものです。これにより、あらゆるシステムのあらゆるデータ型に対して必要な正しいバイト数が自動的に計算されます。
チートシート
任意のデータ型に対して割り当てる正しいバイト数を決定するには、sizeof() 演算子を malloc() と共に使用します。
// 移植性の高いメモリ割り当て
int *ptr = (int*)malloc(sizeof(int));
// 配列の割り当て
int *arr = (int*)malloc(10 * sizeof(int));
double *values = (double*)malloc(5 * sizeof(double));sizeof() 演算子は、システム上でデータ型を格納するために必要なバイト数を返します。これにより、データ型のサイズが異なる可能性がある異なるプラットフォーム間でも、コードの移植性を維持できます。
自分で試してみよう
#include <stdio.h>
#include <stdlib.h>
int main() {
// 要素数を読み込む
int n;
scanf("%d", &n);
// TODO: 以下にコードを記述してください
// 1. malloc() と sizeof() を使用して、n 個の double 値のためのメモリを割り当てる
// 2. 返されたポインタを double* にキャストする
// 3. n 個の double 値を読み込み、割り当てられた配列に格納する
// 4. 割り当てられたメモリ(バイト単位)を計算して表示する
// 5. 平均値を計算し、小数点以下2桁まで表示する
// 6. 最大値を見つけ、小数点以下2桁まで表示する
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。