構造体のメンバーへのポインター:
構造体の特定の項目のメンバー数が固定されていない場合、メンバー数 + ポインタ + ヒープメモリを使用して、実際の状況に応じてメンバーを格納できます。たとえば、各学年の生徒の学年数は次のようになります。不確かな。
使用例:
typedef struct Student
{
int id;
char name[20];
int score_cnt;
float* score;
}Student;
// 定义成员,使用栈内存
Student stu = {1001,"hehe",2};
stu.score = malloc(sizeof(*stu.score)*stu.score_cnt);
free(stu.score);
// 定义成员,使用堆内存
Student* stup = malloc(sizeof(Student));
stup->score = malloc(sizeof(*stup->score)*stup->score_cnt);
メモリ解放:
free(stup->score);
free(stup);
注: 構造体変数が定義されているかどうかに関係なく、ヒープ メモリをメンバ ポインタに個別に割り当てる必要があります。そうでない場合、メンバ ポインタはワイルド ポインタであり、構造体変数の使用後に個別に解放する必要があります。そうしないと、メモリ リークが発生します。
柔軟な配列:
構造体の特定の項目のメンバーの数が固定されていない場合、構造体の最後に長さ 0 の配列を定義できます。この種の配列はフレキシブル配列と呼ばれます。構造体により多くのメモリを割り当てる場合は、変数に割り当てられるメモリが多いほど、柔軟な配列の使用法と呼ばれます。
typedef struct Student { int id; char name[20]; int score_cnt; float score[]; // 柔性数组 }Student; Student* stup = malloc(sizeof(Student)+sizeof(stup->score[0])*len); stup->score = len; for(int i=0; i<stup->score_cnt; i++) { scanf("%f",&stup->score[i]); } free(stup)
メンバー ポインターと柔軟な配列の長所と短所:
メンバー ポインターを使用する場合の欠点は次のとおりです。
1. 使用するのが面倒で、2 回割り当て、2 回解放しなければなりません。
2. リスクが高く、ワイルド ポインタやメモリ リークが発生しやすい。
3. 構造体変数とメンバ ポインタが指すメモリは 2 つの独立したメモリ ブロックであり、メモリの断片化が起こりやすいです。
4. メンバ ポインタは構造内で 4|8 バイトのスペースを占有し、位置合わせとパディングを考慮すると、より多くのメモリが浪費されます。
フレキシブル アレイの利点:
1. 使いやすく、フレキシブル配列に個別にメモリを割り当てる必要はなく、構造変数に追加のメモリを割り当てるだけで済みます。
2. 高いセキュリティ。柔軟な配列は構造内の単なるエラー文字であるため、ワイルド ポインタは使用されません。
3. フレキシブルアレイが使用するメモリブロックは構造体変数と一体化されており、構造体変数のメモリとともに割り当て・解放されるため、メモリリークやメモリ断片が発生しにくいです。
4. メモリを節約するため、フレキシブル配列は構造内の単なるマーカーであり、構造の追加メモリを占有することはありません。構造の総バイト数を計算するとき、フレキシブル配列は計算に含まれません。
フレキシブル アレイの欠点:
この構文は C99 構文標準で提案および実装されましたが、C89 のみをサポートしていた初期のコンパイラではこの使用法がサポートされておらず、汎用性が低かったです。