メモリ確保での sizeof() の使用
CoddyのCジャーニー「論理と制御フロー」セクションの一部。レッスン 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()を使用すると、データ型のサイズが異なる可能性のあるさまざまなシステムでコードが正しく動作し、特定の型の要素を指定した数だけ格納するために領域を確保する意図も明確に伝わります。
チャレンジ
簡単動的メモリ割り当てで sizeof() と malloc() を適切に使用する方法を示す C プログラムを作成してください。プログラムでは、次の処理を行います。
- 割り当てる要素数を表す整数
nをユーザーから読み取る malloc()とsizeof()を使い、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() を使用することで、動的メモリ割り当ての移植性と保守性を高め、あらゆるシステム上のあらゆるデータ型に必要なバイト数を自動的に正しく計算できることを学びます。
自分で試してみよう
#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;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理と制御フローのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ