28

私は、関数を早期に終了させる可能性のある多くの障害点があるコードのセクションに取り組んでいます。私が操作しているライブラリでは、Cスタイルの配列を関数に渡す必要があります。したがって、すべての出口点で配列に対してdeleteを呼び出す代わりに、次のようにします。

void SomeFunction(int arrayLength)
{
   shared_ptr<char> raiiArray(new char[arrayLength]);
   pArray = raiiArray.get();

   if(SomeFunctionThatRequiresCArray(pArray) == FAILED) { return; }

   //etc.
}

を使用したかったunique_ptrのですが、現在のコンパイラはそれをサポートしておらず、この場合、参照カウントのオーバーヘッドは実際には問題になりません。

レガシーコードとインターフェイスするときに、このプラクティスについて誰かが考えているかどうか疑問に思っています。

UPDATEの代わりにshared_ptr呼び出す ことを完全に忘れました。メモリリークは見られなかったので、それを使用することにしました。ベクトルを使うことすら考えていませんでした。最近、新しい(私にとって)C ++を調べているので、「持っているツールがハンマーだけだと、すべてが釘のように見える」というケースがあると思います。症候群。フィードバックをお寄せいただきありがとうございます。deletedelete []

UPDATE2質問を変更して、同じ間違いを犯した人にとってもう少し価値のあるものにするための回答を提供すると思いました。scoped_array、、などの代替手段がありshared_arrayますvectorが、を使用しshared_ptrて配列のスコープを管理できます(ただし、この後、なぜそうしたいのかわかりません)。

template <typename T>
    class ArrayDeleter
    {
    public:
        void operator () (T* d) const
        {
            delete [] d;
        }
    };

void SomeFunction(int arrayLength)
    {
       shared_ptr<char> raiiArray(new char[arrayLength], ArrayDeleter<char>());
       pArray = raiiArray.get();

       if(SomeFunctionThatRequiresCArray(pArray) == FAILED) { return; }

       //etc.
    }
4

6 に答える 6

28

動的に割り当てられた配列へのポインターを使用しshared_ptrたり保持したりしないでください。scoped_ptrshared_ptr と scoped_ptr はdelete ptr;、ポインターが参照されなくなった/スコープ外になったときにクリーンアップするために使用され、動的に割り当てられた配列で未定義の動作を引き起こしました。代わりに、破棄時に正しく使用される shared_array または scoped_array を使用してdelete[] ptr;ください。

質問に答えるには、スマート ポインターを渡さない場合は、 を使用します。scoped_arrayオーバーヘッドが より少ないためですshared_array

または、配列ストレージとして使用std::vectorします (ベクトルは連続したメモリ割り当てが保証されています)。

于 2010-07-16T15:34:20.323 に答える
15

を使用するか、配列を処理している場合はboost::scoped_arrayさらに適切です。std::vector

于 2010-07-16T15:34:04.927 に答える
7

単にを使用することを強くお勧めしstd::vectorます。の要素vectorsはヒープに割り当てられ、vectorスコープから外れると、関数を終了するたびに削除されます。

vectorCスタイルの配列を必要とするレガシーコードにを渡すには、単にを渡し&vectorName[0]ます。要素はメモリ内で連続していることが保証されています。

于 2010-07-16T15:38:10.953 に答える
5

これがありboost::scoped_ptrます。

于 2010-07-16T15:30:42.300 に答える
3

これ

shared_ptr<char*> raiiArray(new char[arrayLength]);

これは良い習慣ではありませんが、演算子new[]shared_ptr使用して割り当てるため、未定義の動作を引き起こしますがoperator delete、メモリを解放するために使用します。使用する正しいことはboost::shared_array、カスタム削除機能を追加することです。

于 2010-07-16T15:37:25.907 に答える