2016-07-11 8 views
3

なぜそれが宣言されたサイズを持つベクトルがそうのようなcinからの直接入力を受け付けることができるということです。サイズを指定せずに宣言されたベクトルは、なぜ入力をcinに受け入れるためにpush_backを必要としますか?

int n; 
cin>>n; 
vector<int> a(n);//Vector declared with size 
for(int i=0;i<n;i++) 
    cin>>a[i]; 

しかし、大きさせずに宣言ベクトルのような入力を受け入れるようにpush_back()機能を必要とします。

int n; 
cin>>n; 
vector<int> a;//Vector declared WITHOUT size 
int input; 
for(int i=0;i<n;i++){ 
    cin>>input; 
    a.push_back(input); 
} 

答えて

3

ベクター上[]オペレータの使用が指定されたインデックスのオブジェクトが有効であると仮定しています。 vectorがこのインデックスに適合する内部バッファを割り当てていない場合、これは未定義の動作です。あるいは、push_back()は、単にvectorの末尾に追加し、必要に応じてより大きな内部バッファを再割り当てするため、同じ方法で未定義の動作を実行することはありません。 []でアクセスする前にベクトルのサイズを明示的に変更すると、アクセスする要素0n-1が定義されていますが、n-1を超えるものは未定義の動作になるように配列のサイズが変更されます。

1

をその

vector<int> a(n); 

n要素を使用してベクトルを事前に割り当てられるため

vector<int> a; 

にはない、とあなたは要素を一つずつ追加している間などsが、here (see constructor variant (2) please)を述べました。


あなたはstd::vectoroperator[]を使用している場合、それは、要素が使用されたインデックスに存在する、すなわち、インデックスがstd::vector<T>::size()未満でなければならないことを、保証する必要があります。

1

最初の例では、n要素の場所を予約するベクトルコンストラクタを使用し、ランダムアクセス演算子を使用できます。ランダムアクセス演算子がメモリのサイズをチェックしていません。

2番目のコードでは、空のベクターを作成しています。 intオブジェクトのメモリ割り当ての追加ステップにはpush_backが必要です。

コンストラクタ関数を有するCPP基準:(3)におけるhttp://en.cppreference.com/w/cpp/container/vector/vectorルック

1

理由は非常に簡単です。サイズを宣言すると(kとしましょう)、k個の要素を割り当てます。シーンの後ろにT * vec =新しいT [k]があります。いったんk要素が存在するだけでなく、それがデフォルト値であれば、何らかの種類のコールが呼び出されます。

私たちはstd :: vector vのようなことをします。 サイズが0であるため、何も配置されていないので、push_backまたはemplace_backを使用してスポットを作成する必要があります(コピーコンストラクタを使用せずに直接ビルドするので、前のscerinoに存在しないアドレスにアクセスする

1

最初のベクトルは事前に割り当てられているため、演算子[]で特定の要素を参照できます。

いくつかの要素をプッシュする前に2番目のベクトルで演算子を使用する場合、その動作は未定義です。

+1

いいえ、ベクトルは 'op []'に例外をスローしません。 –

+0

私の悪い、固定(: – stryku

関連する問題