2016-12-06 4 views
1

私はこのトピック(配列)で私の意見ではあまり明確ではない、C++のStroustrupの本を勉強しています。ベクトルダイナミックとスタティックの配列

std::vector<int> a; 

a.push_back(10); 
a.push_back(487); 
a.push_back(-22); 

と呼ばれている

int test[3] = {10,487,-22}; 

のように宣言されている

静的配列動的配列:私はC++が(デルファイのような)アレイの2種類があります理解しているものから、私はすでにこれについての回答を見てきましたが(そこにはたくさんの行と概念がありました)、彼らは私にその概念を明確にしませんでした。私はvectorのを理解しているものから


は、より多くのメモリを消費しますが、彼らは(実際には、動的に)そのサイズを変更することができます。代わりに、配列はコンパイル時に与えられる固定サイズを持ちます。

Stroustrupの章では、配列が存在しない間はベクタが安全である理由を説明していないと述べています。私は彼を本当に信じますが、なぜですか?安全の理由は記憶の場所に関連しているのでしょうか? (ヒープ/スタック)

なぜ安全であればベクターを使用しているのですか?

+0

これは、std :: vector、配列、およびポインタを使用してメリットと落とし穴について質問する場合、非常に幅広い議論です。 –

+0

私のコードでは、古いバージョンでそれらを使用した人が見つかった場合にのみ、常にベクトルと配列を使用します。しかし、私はなぜ –

+0

std :: vectorが以前に配列で解決されたほとんどのタスクを引き継いだ、よく磨かれたマシンであるかを知りたいと思います。 std :: vectorがどのように設計されているのか、その理由を調べたいと思うでしょう。これには、リソース管理(3/5のルール)とアルゴリズム的な振る舞いが含まれます。 –

答えて

3

アレイが安全でない理由は、メモリリークのためです。

あなたは、動的配列

int * arr = new int[size] 

を宣言すると、あなたは[] arrが、その後、メモリは未確認のまま、これはメモリリークとして知られ、削除しないと。注意すべき点は、C++でnewという単語を使用するときはいつでも、そのメモリを解放するためにどこかに削除がなければならないということです。 malloc()を使用する場合は、free()を使用する必要があります。

http://ptolemy.eecs.berkeley.edu/ptolemyclassic/almagest/docs/prog/html/ptlang.doc7.html

また、そのサイズ-1より大きいインデックスの値を挿入例えば、アレイ内の境界の外に出ることは非常に容易です。ベクタを使用すると、必要な数の要素をpush_back()することができ、ベクタは自動的にサイズ変更されます。サイズが15の配列があり、arr [18] = xと言うと、 とすると、セグメント化エラーが発生します。プログラムはコンパイルされますが、配列境界から外す文に達するとクラッシュします。

大規模なコードを使用すると、配列が頻繁に使用されません。ベクトルは客観的にはほとんどあらゆる点で優れているため、配列を使用することは無意味になります。

EDIT:ポール・マッケンジーは、セグメンテーションフォールトを保証するものではありません配列境界の出入り、コメントで指摘したのではなく、未定義の動作があると何が起こるかを決定するために、コンパイラに任されたよう

+0

彼らはより多くのスペースを必要としますが、全体的に私はベクトルを好むべきです。私は "安全"がどこにあるのか理解していると思います:)また、ベクトルは多くの便利な方法で実装できます。配列は "古代"であり、Cのレトロな互換性のために使用することができます –

+0

これは本当です。ベクトルはより多くのストレージを使いますが、これはベクトルに付随するセキュリティ/効率の利点と比較して漠然としています –

+2

@ConnorSchwinghammer - *サイズ15の配列を持ち、arr [18] = xと言うと、セグメント化エラー* - ベクトルに対して '[]'を使用して領域外に出た場合、セグメンテーション違反は保証されません(デバッグVisual C++ランタイムはチェックしますが、リリースバージョンはチェックしません)。したがって、境界外に出たときには通常の配列を使用するのと同じ未定義の動作が基本的に発生します。しかし、 'vector'には' at() '関数があります。これは、インデックスが範囲外であれば、' std :: out_of_range'例外がスローされることを保証します。だから、あなたの答えを修正する必要がありますか? – PaulMcKenzie

-4

私が見ることができるセキュリティの1つは、あなたがそこに存在しないベクトルの何かにアクセスできないということです。

私が指摘したことは、push_back要素が4つしかなく、インデックス7にアクセスしようとすると、エラーが返されるということです。しかし、配列では起こらない。

要するに、破損したデータへのアクセスを停止します。

編集:

プログラマがエラーをスローするvector.size()を使用して索引を比較することがあります。自動的には実行されません。自分自身でそれをやる必要があります。

+0

これは、ほとんどの場合、間違いです。 –

+0

@CaptainGiraffe、私はインデックス番号を使う前のように、vector.size()と比較して、それが外れているかどうかを判断できます。 –

+0

これは、配列の合理的な使用の場合も同様です。 –

2

私たちは見てみましょうファイルから数値を読み取る場合。
ファイル内にいくつの番号があるのか​​わかりません。

数値を保持する配列を宣言するには、容量または量を知る必要があります。これは不明です。ファイル番号が64より大きい場合は、配列の上書きを開始します。ファイルのサイズが64未満(16の場合)の場合、メモリを無駄にしています(48スロットを使用しないことにより)。私たちが必要とするのは、コンテナ(配列)のサイズを動的に調整することです。

アレイの容量を動的に調整するには、新しい大きなアレイを作成してから要素をコピーし、古いアレイを削除する必要があります。

std::vectorは、必要に応じて容量を調整します。あなたのためのメモリの動的割り当てを処理します。

もう1つの側面は、コンテナを関数に渡すことです。配列では、配列と容量を渡す必要があります。 std::vectorでは、ベクターを渡すだけで済みます。ベクトルオブジェクトは、その容量について問い合わせることができます。

関連する問題