構造体の配列はどのように割り当てられますか
あなたの場合、MyData[2]
配列はメモリ内で次のようになります。
| count | name | average | count | name | average |
^ -- your ptr points here
これは、 size の単一の連続空間2 * sizeof (struct MyData)
です。
操作を実行するたびにptr++
、ポインターは配列内の次の構造体に移動します。つまり、単一の のサイズが考慮されますstruct MyData
。
| count | name | average | count | name | average |
^ -- after ptr++ your ptr points here
次々と、ポインタは配列の直後ptr++
のメモリを指します。
| count | name | average | count | name | average |
^ -- another ptr++ and your ptr points here
ポインターを逆参照するptr
と、まだ使用されていない、または割り当てられていないメモリにアクセスします。これは未定義の動作であり、そのためアプリケーションがクラッシュします。
反復する方法は?
それにはいくつかの方法があります。すべての場合にすべての方法が適用できるわけではないことに注意してください。
シンプルな
多くの場合、単に配列のサイズを知っているだけです。その後、通常のfor
ループを使用してコンテンツを反復処理できます。
int len = 2;
struct MyData data[len] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;
for (int i=0; i<len; i++, ptr++ ) {
// do your thing with the ptr
// and note that ptr gets increased inside for
}
sizeof を使用して配列の長さを決定する
struct MyData data[2] = { {3, "name1", 1.0}, {5, "name2", 2.5} };
struct MyData* ptr = data;
struct MyData* endPtr = data + sizeof(data)/sizeof(data[0]);
while ( ptr < endPtr ){
// do your thing with the ptr
ptr++;
}
は要素のsizeof(data)/sizeof(data[0])
量を計算します。配列の合計サイズを取得し、それを 1 つの要素のサイズで割ります。
この方法には欠点があります。配列がポインタとして宣言されている場合は使用できません! たとえば、配列をパラメーターとして関数に渡すと、通常はポインターに変換され、配列のサイズを決定できません。