C言語の構造体における柔軟な配列メンバー(Flexible Array Member)の使い方
柔軟な配列メンバー(Flexible Array Member)とは
C言語の構造体における柔軟な配列メンバー(Flexible Array Member)とは、構造体内で配列のサイズ(次元)を指定せずに宣言できる特殊なメンバーのことです。実際のサイズは実行時に動的に決定されるため、「柔軟(フレキシブル)」と呼ばれます。
柔軟な配列メンバーを使用する際は、以下のルールを守る必要があります。
- 柔軟な配列メンバーは、必ず構造体の最後のメンバーとして宣言する
- 構造体には、柔軟な配列メンバー以外に少なくとも1つの名前付きメンバーが必要
- この機能は C99規格 で標準化されている
サンプルコード
以下は、従業員情報を格納する構造体に柔軟な配列メンバーを使用した例です。名前の長さに応じて必要なメモリだけを malloc() で確保しています。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// employee型の構造体。柔軟な配列メンバー以外に、
// 少なくとも1つの名前付きメンバーが必要。
struct employee
{
int emp_id;
int name_len;
int emp_size; // 'emp_size'変数は、柔軟な文字配列emp_name[]のサイズを保存するために使用
char emp_name[]; // 柔軟な配列メンバーemp_name[]は、構造体の最後のメンバーでなければならない
};
struct employee *createEmployee(struct employee *e, int id, char a[])
{
// メモリ割り当て:構造体のサイズ+名前の文字数分のメモリを確保
e = (struct employee *)malloc( sizeof(*e) + sizeof(char) * strlen(a));
e->emp_id = id;
e->name_len = strlen(a);
// ユーザーが指定した配列a[]のコピーであるemp_nameのサイズに応じてサイズを設定
strcpy(e->emp_name, a);
return e;
}
void printEmployee(struct employee *e) // 従業員の詳細を出力
{
printf("Employee_id : %d\n" "Employee Name : %s\n" "Name Length: %d\n\n", e->emp_id, e->emp_name, e->name_len);
}
int main()
{
struct employee *e1 = createEmployee(e1, 26, "Ram");
struct employee *e2 = createEmployee(e2, 53, "Madhu");
printEmployee(e1);
printEmployee(e2);
printf("Size of structure Employee: %lu\n",
sizeof(struct employee));
return 0;
}
実行結果
Employee_id : 26 Employee Name : Ram Name Length: 3 Employee_id : 53 Employee Name : Madhu Name Length: 5 Size of structure Employee: 12
コードの解説
このプログラムのポイントを整理します。
- createEmployee関数:
malloc()を使って「構造体本体のサイズ+名前の文字数分」のメモリを一度に確保します。これにより、構造体と名前データが連続したメモリ領域に配置され、メモリ管理が効率的になります。 - strcpy()によるコピー:引数で渡された文字列
a[]を、柔軟な配列メンバーemp_name[]にコピーします。あらかじめ必要な分のメモリを確保してあるため、安全に書き込めます。 - sizeof(struct employee):柔軟な配列メンバーは
sizeofの計算に含まれないため、結果は12バイト(int型3つ分)となります。
このように柔軟な配列メンバーを使うと、可変長データを1回のメモリ確保で扱えます。そのため、連結リストやネットワーク通信のパケット構造など、可変長データを含むデータ構造の実装において特に有用な機能です。
-
データ構造入門:多次元配列を表す「配列の配列」とは?仕組みと実装方法を解説
多次元配列のもう一つの表現方法:「配列の配列」 データ構造において、多次元配列を扱う方法はいくつか存在します。本記事では、その中でも「配列の配列(Array of Arrays)」と呼ばれる表現方法について詳しく解説します。 この形式では、1つの親となる配列が、複数の配列それぞれの先頭アドレスを保持するという構造になっています。イメージとしては以下のようになります。 配列の配列の構造 上図は、サイズ [7 × 8] の2次元配列 x を表しています。この構造では、各行が独立した1次元配列として扱われ、最初の配列(親配列)がこれらの個々の配列へのアドレスを格納しています。 つまり、親配列の中身
-
データ構造:単一の配列で複数のリストを実現する方法
配列表現におけるメモリの無駄の問題 データ構造における配列による表現は、時間とともに変化するデータを格納する場合、基本的にメモリ領域を無駄にしてしまう傾向があります。あるデータを格納するためには、複数の値を余裕をもって格納できるサイズの配列を事前に確保しておく必要があり、多くの場合、配列の拡張には「配列倍増(アレイ・ダブリング)」という手法が用いられます。 配列倍増の仕組みとその課題 具体的な例で考えてみましょう。現在の配列サイズが8192であり、すでに満杯になっているとします。この場合、配列倍増の手法によってサイズを拡張する必要があり、新しい配列のサイズは16384になります。その後、旧配