6

私が扱っているコード ベースは、記述が不十分でメモリ リークが多いコード ベースです。

主に動的配列として使用される生のポインターを含む多くの構造体を使用します。

多くの場合、構造体は関数間で渡されますが、これらのポインターの割り当てと割り当て解除はランダムな場所に配置され、簡単に追跡/推論/理解することはできません。

それらのいくつかをクラスに変更し、それらのポインターをクラス自体によってRAIIされるようにしました。それらはうまく機能し、実装に時間を費やしたくないという理由だけで、これらのクラスのコピー構成とコピー代入を禁止したことを除けば、見栄えも悪くありません。

今私は考えています、私は車輪を再発明していますか?C スタイルの配列を std:array または std::valarray に置き換えてみませんか?

ヒープメモリと RAIIed を使用するため、std::valarray をお勧めします。std::array は、私の開発環境では (まだ) 利用できません。

Edit1 : std::array のもう 1 つのプラスは、これらの動的配列の大部分が POD (ほとんどが int16_t、int32_t、および float) 配列であり、数値 API によって作業が楽になる可能性があることです。

始める前に知っておくべきことはありますか?

私が考えることができる 1 つは、std::valarray または std::array を C スタイルの配列に変換する簡単な方法がない可能性があり、コードの一部はポインター演算を使用しており、データをプレーンな C として表示する必要があるということです。スタイルの配列。

他に何か?

編集2

最近この質問に出会いました。非常に悪い点std::valarrayは、C++11 まで安全にコピー代入できないことです。

その回答で引用されているように、C++03 以前では、ソースと宛先のサイズが異なる場合は UB です。

4

3 に答える 3

13

C スタイルの配列の標準的な置き換えはstd::vector. std::valarray数値計算のようなものを行うための「奇妙な」数学ベクトルです。実際には、任意のオブジェクトの配列を格納するようには設計されていません。

そうは言っても、使用することstd::vectorはおそらく非常に 良い考えです。リークを修正し、ヒープを使用し、サイズ変更可能で、優れた例外安全性などを備えています。

また、データが 1 つの連続したメモリ ブロックに格納されることも保証されます。メンバー関数を使用して、上記のブロックへのポインターを取得できますdata()。C++ 11 より前の場合は、&v[0]空でない vector を使用しvます。その後、通常どおりポインター ビジネスを実行できます。

于 2015-01-30T14:27:01.473 に答える
6

std::unique_ptr<int[]>所有するためのドロップイン代替に近いint*です。それ自体を暗黙的にコピーするのではなく、暗黙的に移動するという優れた特性があります。

コピーする操作は、実行時の非効率性ではなく、コンパイル時のエラーを生成します。

int*また、破壊時のヌルチェック以外に、その所有に対する実行時のオーバーヘッドはほとんどありません。.より多くのスペースを使用しませんint*

std::vector<int>3 つのポインターを格納し、暗黙的にコピーします (コストがかかる可能性があり、既存のコードの動作と一致しません)。

私はstd::unique_ptr<int[]>最初のパスとして始めて、それを機能させます。std::vector<int>インテリジェントなバッファ管理が価値があると判断した後、いくつかのコードを移行するかもしれません。

memcpy実際、最初のパスとして、RAII メンバーの追加を開始する前に、memsetおよび類似の関数を探して、それらが問題の構造で動作していないことを確認します。

Astd::unique_ptr<int[]>は、構造体に対してデフォルトで作成されたデストラクタが、新しいコードを記述する必要なく、RAII クリーンアップを実行することを意味します。

于 2015-01-30T14:55:45.693 に答える
5

std::vector私はCスタイルの配列の代わりとして好むでしょう。以下を介して、基になるデータ(ベアポインターのようなもの)に直接アクセスできます.data()

要素ストレージとして機能する基になる配列へのポインターを返します。

于 2015-01-30T14:27:09.567 に答える