2016-09-09 6 views
0

私はここでたくさん検索しましたが、C++の高度な初心者のための私の正しい説明はありません。以前は構造体のベクトルで作業していましたが、現在はセグメンテーションフォールトが発生しています...C++構造体のベクタを初期化する正しい方法

このようなオブジェクトが実際にどのように機能するのか、それが正しい方法であるかを知りたいのですが!私はそれのサイズを変更し、値でそれを埋める前に

std::vector<numberOfSpecies> size; 

は私が

struct numberOfSpecies { 
    int predator; 
    int prey1; 
    int prey2; 
}; 

のような構造体と、それのベクトルを持っています。

size.resize(100); 

これは実際に何をしていますか?これは構造体のための権利ですか? それがゼロで初期化されているように見えます...

は今、私はこのようなをしています:

size[t].predator=0; 
size[t].prey1=0; 
size[t].prey2=0; 

for(int k = 0; k < N; ++k){ 
    size[t].predator++; 
    size[t].prey1++; 
    size[t].prey2++; 
} 

は、この権利ですか?起こりうる問題はどこですか?それをより良くするには?

+0

resizeは 'n '個の構造体を作成しますが、あなたは(デバックモードを使用しているため)事故で0で初期化されるだけです。あなたはそれを使用する方法のサイズを変更した後、各値にランダムな未定義の値があると仮定する必要があります。 – Hayt

+0

助けてもらえますか?値は何ですか 't'ですか?セグメンテーションフォルトはどこで発生しますか?もう少しコードを追加してください。好ましくは、http://stackoverflow.com/help/mcveの方法で – Hayt

+0

@Haytあなたは0での初期化のために確かに事故ですか?私はいつもresizeがオブジェクトのコンストラクタを呼び出すと考えています。この場合、デフォルトのコンストラクタはすべてのメンバを0にします。 – Garf365

答えて

3

ここで、最も簡単で「正しい」解決策はただ、

size.resize(100,{0,0,0}); //aggregate initialization 

for(int k = 0; k < N; ++k) 
{ 
    size[t].predator++; 
    size[t].prey1++; 
    size[t].prey2++; 
} 
のようなものを集計初期化(あなたがC++ 11と上へのアクセス権を持っている場合)とベクトルオブジェクトに属し resize()機能を使用することが考えられます

numberOfSpeciesオブジェクトのすべてのメンバーは0に初期化されます。

+2

"中間"の代替案は 'reserve'と' push_back'です。しかし、デフォルト値ですべてを初期化したい場合は、ここで 'resize'が良いでしょう。 – Hayt

+0

デフォルトでは、 'std :: vector :: resize'はデフォルト値を実行するので、' {0,0,0} 'は' resize'の第2引数として(害はありませんが)初期化は、集約の場合、[ゼロ初期化](http://en.cppreference.com/w/cpp/language/zero_initialization)を意味します。 – vsoftco

+0

@vsoftcoどのような理由であれ、メンバーを別の値に初期化したい場合や、他の誰かが質問を検索したい場合は、大文字と小文字の区別なく、構文を表示するためにそれを含めました。 – George

-1

デフォルトコンストラクタを構造体に追加できます。新しいコードは次のようになります:

struct numberOfSpecies { 
    numberOfSpecies(): predator(0), prey1(0), prey2(0) { } // default constructor 
    int predator; 
    int prey1; 
    int prey2; 
}; 

このように、サイズ変更が適用されると、構造体はベクター内で適切に初期化されます。

+1

または、C++ 11の場合: 'struct numberOfSpecies { int predator = 0; int prey1 = 0; int prey2 = 0; }; ' – Garf365

+2

「正しく初期化されている」とは、コンストラクタなしでも同様です。あなたのコンストラクタは明示的な0だけですが、 'resize'仕様によると、すでにベクトル内部で正しくゼロに初期化されています。デフォルトで0以外の値が必要な場合は面白いです – Garf365

+1

@ Garf365または、少なくともC++ 03以降はコンストラクタをそのままにしておきます。この場合は違いはありません:-) – juanchopanza

1

これ:

size[t].predator=0; 
size[t].prey1=0; 
size[t].prey2=0; 

sizet番目の要素にゼロ書き込む - または有用であってもなくてもよい。

この:

for(int k = 0; k < N; ++k){ 
    size[t].predator++; 
    size[t].prey1++; 
    size[t].prey2++; 
} 

t thをインクリメントします要素はsize N回です。これは非常に有用であるとは思われません。

size[0].predator=0; // Technically not needed because .resize() 
size[0].prey1=0;  // will have initialized it to zero anyway 
size[0].prey2=0;  // *BUT* explicit is always better than implicit. 

// Initialize each element of size to be one greater than previous. 
for(int k = 1; k < N; ++k){ 
    size[k].predator = size[k-1].predator + 1; 
    size[k].prey1 = size[k-1].prey1 + 1; 
    size[k].prey2 = size[k-1].prey2 + 1;; 
} 
関連する問題