2016-03-26 17 views
0

struct playerの可変長バッファを関数内から初期化する必要があります。これまでのところ、これは私が思いついたものです:関数内のスタック上に構造体を作成し、それを別の関数で作成された配列の配列の位置に代入する

#include<stdio.h> 
#include<stdlib.h> 

struct player{ 
    char name; 
}; 

void players_init(struct player **players){ 
    *players = malloc(2 * sizeof(struct player)); 
    struct player p1, p2; 
    p1.name = 'X'; 
    p2.name = 'Y'; 

    (*players)[0] = p1; 
    (*players)[1] = p2; 
} 

int main(int argc, char *argv[]) 
{ 
    struct player *players = NULL; 
    players_init(&players); 
    printf("%c\n", players[0].name); // prints X 
    printf("%c\n", players[1].name); // prints Y 

    return 0; 
} 

私の質問は:私は、関数内からp1p2を作成していますので、これらの二つの変数は、同じ機能専用のスタックフレームに割り当てられるべきです、その関数が終了すると、それらの変数はなくなるはずです。

私の例からわかるように、別の関数で作成されたバッファplayersの位置にこれらの変数を割り当てます。

players_initが終了すると、私の理解からは、もはや存在してはならない変数を参照しているので、私のコードがなぜ機能するのか疑問に思っています。

私には何が欠けていますか?

+0

メイク 'それを 'char'という名前で渡します。それから、次のように呼び出します: 'players_init(&players、 'X'); players_init(&players、 'Y'); ' これは、既存のコードが正しく動作するように見せかける、初期化されていないメモリを上書きするため、期待どおりにコードが破損する可能性があります。 – sehrgut

答えて

1

構造体全体を配列にコピーしているので、それは機能します。 p1p2のアドレスだけを使用していた場合は、p1とp2`が範囲外になるため、未定義の動作が発生します。

あなたの場合は簡単ですが、現実の世界でだけでは構造体のコピーを行っているに注意して、あなたがコピーされたビットを知る必要があり、これではありません

で一人のプレイヤーを初期化players_init`
+0

したがって、理論的には、構造体のコピーが作成されているので、 'struct player'変数' p'を作成し、割り当て前に 'name'フィールドを変更するだけです...? – nbro

+0

はい。 'p1'と' p2'を 'p'に置き換え、同じ' p'を使って配列の中のアイテムを次々に初期化することができます。それはあなたが意味することですか? – John3136

+0

はい。ありがとう!このチュートリアルでは、このチュートリアルに関連する問題、つまり厳密に慎重にしなければならないときなどについて説明します。 – nbro

関連する問題