5

MPC コントローラーを C++ で作成しました。これには Matrix クラスが含まれ、データを配列に格納し、C メモリ関数 (memcpy、memset など) を使用しました。今日、私は配列をC ++ベクトルに置き換え、コピーを使用してメモリを移動しました... 1つの問題に直面しました。配列をベクトルに置き換えることで、ベクトルを使用することで制御信号の計算時間がほぼ2倍になりました。

alloc、memcpy、memset、free ins C++ コードを使用している場合、不利な点はありますか? あるとすれば、それらは何ですか?

4

5 に答える 5

2

手動のメモリ管理を使用すると、より多くの作業を行う必要があります。したがって、エラーを起こす機会が増えます。

C++ では、ほとんどの場合、手動のメモリ管理が間違っています。ネイキッド配列が本当に必要な場合は、少なくともboost::scoped_arrayorのようなラッパーを使用する必要がありますboost::shared_array。また、std::unique_ptrを使用して配列を管理できます。

于 2012-11-26T08:59:31.887 に答える
2

Vector次の 2 つの側面で価値を付加します。

  1. Cサイズ変更、現在のサイズのチェックなど、配列には存在しない追加機能を提供します。そのインターフェイスからカスタム ソリューションへのより良い代替手段を見つけることができます。
  2. の範囲外のアドレスのアドレス指定など、いくつかのバグをキャッチしますvector

独自のデータ管理に満足し、コードの品質に自信がある場合は、必要ありませんvectorCただし、これにより、配列の保守性が低下するなど、ソフトウェアの問題が発生する可能性があることに注意してくださいvector(たとえば、現在のコードでは範囲外の値にアクセスしない場合でも、将来のコードでは範囲外の値にアクセスする可能性があります)。

編集:あなたのケースで考えられる代替案については、@Alsの回答を参照してください(std::array)。

于 2012-11-26T09:02:33.257 に答える
1

多くのオブジェクトを挿入または削除する場合、ベクトルには1つの主要な(比較的言えば)問題がありますが、ここでは関係のないベクトルの最初/中間に挿入する場合(配列にも同じ問題があります)があります。

実行する挿入が多数ある場合は、通常reserve、挿入の前に呼び出しを追加します。次のように呼び出しますvector.reserve(<best guess number of objects to be inserted>)

これは、ご存じのとおり、vector が必要に応じてメモリを割り当てるためです。一度に多数のアイテムを挿入する場合、多くの再割り当て/コピーが必要になり、多くの時間を消費する可能性があります。

この問題には他の解決策があります。std::deque1 つは、ベクター全体を毎回コピーしないなどの場合に、少し効率的なこれを使用することです。またはstd::array、C 配列のベクター スタイル ラッパーである which を使用します。

編集:タイトルは変更されましたが、この情報はまだ役立つかもしれません..

于 2012-11-26T08:59:13.867 に答える
1

コンパイル時に配列のサイズがすでにわかっている場合は、実際にstd::arrayは配列を使用する方が適切ですが、動的配列が必要な場合は、std::vector.

Vector の代わりに Array を使用している場合、不利な点はありますか?

std::vector. _

ただし、ほとんどの場合、パフォーマンスの利点は、プロファイラーが問題として指摘しない限り、ほとんどの場合重要ではないことに注意してください。

alloc、memcpy、memset、free ins C++ コードを使用している場合、不利な点はありますか? あるとすれば、それらは何ですか?

C++ で C スタイルのメモリ割り当ておよび管理関数を使用するべきではありません。欠点は次のとおりです。

  • C++ では、避けられない場合を除き、動的割り当てを使用しないでください。むしろ、スマート ポインターを使用する必要があります。これが、C++ がスマート ポインターを提供するまさにその目的です。
  • また、手動のメモリ管理では間違いが起こりやすくなります。C++ を使用しているため、コードの将来のメンテナーは、 ed ポインターを使用して呼び出すと想定し、 UB を引き起こす可能性があります。newdeletemalloc
  • C スタイルの関数を使用することのもう 1 つの欠点は、newオブジェクト コンストラクターを呼び出さないため、オブジェクトが初期化されないままになることです。
于 2012-11-26T09:03:48.000 に答える
0

std::vector と raw 配列の間で注意すべき違いの 1 つは、std::vector はコピーを作成するときに要素のコピー コンストラクターとコピー代入演算子を呼び出すのに対し、raw 配列では自分で行う必要があることです (たとえば、次のような関数「memcpy」はコピー コンストラクター/代入演算子を呼び出しません)。

配列の要素がプリミティブ型または POD 型の場合は問題ありません (POD 型、Plain Old Data は基本的に、パブリック データ メンバーのみを持ち、基底クラスを持たないクラスまたは構造体です)。

この違いこそが、生の配列でパフォーマンスが向上した理由です。つまり、コピーの回数が減ります。C++11 では、右辺値参照とムーブ コンストラクター/代入演算子を使用してこの問題を最小限に抑えていますが、それでも手動で処理されるメモリに勝るものはありません。

しかし、コード内のあらゆる場所でメモリを直接処理することは、とにかく悪い考えです。メモリ リーク、非例外セーフ コードにつながる可能性があり、コードが過度に長く複雑になります。POD 型専用に設計された独自の配列クラスを作成できます。これにより、std::vector のような配列クラスの利便性と安全性、および生の配列の効率性を得ることができます。

于 2012-11-26T09:21:22.873 に答える