0

ベクトルやキューなどのSTLコンテナに大きなデータ配列(データのチェック、サイズなどの基本機能を保持するクラス内に格納)を配置する方法を探しています(プロデューサーがあるため、FIFOキューが最適です)および消費者)。

問題は、コピーコンストラクターを実装する必要があることです..まあ..ディープコピーを作成したくありません(時間がかかりすぎるため、浅いコピーに固執します)が、もう一度持っていますデストラクタ内のデータの配列を削除するタイミングがわからないという問題 (デストラクタを 2 回呼び出し、データは 1 回しかないため、さらに、デストラクタへの最初の呼び出しは、コンテナー内の要素の挿入/移動から発生する可能性が高いため、その時点でまだ配列データが必要です)。

データ配列に std::shared_ptr のようなスマート ポインターを使用することを考えましたが、私が読んだところによると、delete [] ではなく delete を呼び出します。通常の配列 [] があるので残念です。

現在、クラスをコンテナーから削除する前に、クラスで「DeleteArray」関数を手動で呼び出すソリューションがあります。それはうまくいきますが..それは良くありません。

何か案は?

4

6 に答える 6

3

Boost には のshared_arrayようなクラスがありますshared_ptrが、 を使用するdelete[]か、カスタムのデリータを追加しshared_ptrて を呼び出すことができますdelete[]

于 2011-01-23T22:48:08.040 に答える
1

さらに良い解決策はshared_ptr、大きなオブジェクトに s をコンテナに入れ、高価なコピーをまとめて避けることです。

編集 0:

もちろん、もう 1 つのオプションは、オブジェクト自体を軽量にして .NET でコピー可能にすることshared_arrayです。エレミヤが示唆するように。

于 2011-01-23T22:50:54.747 に答える
1

配列を使用しないでくださいstd::vector。代わりに a を使用してください。次に、スマート ポインターでそれをポイントします。

于 2011-01-23T22:48:50.690 に答える
0

コピー コンストラクターで単純な参照カウントを実装できます。削除するたびに参照を減らすことができます。

于 2011-01-23T22:54:38.263 に答える
0

洞察に満ちたすべての回答に感謝します。

これは、前回この問題が発生したときに、自分自身をコピーせずにキューをハンドコーディングした理由を思い出させてくれます。素敵でクリーンなバージョンを実行する方法を理解するよりも、はるかに時間がかかったとは言えません。:)

だから..私がしたことは次のとおりです。

解決策 a) 元の投稿で説明したように、ベクトルからクラスを削除する前に明示的に呼び出さなければならない関数を作成しました。良くはありませんが、うまく機能し、他に何もいじる必要はありませんでした。呼び出すことを忘れないでください。

解決策 b) 配列をさらに別のクラスに配置し、そのクラスへのスマートポインター (shared_ptr) を使用しました。本当にうまくいきました。vector の要素として shared_ptr も使用する必要がありました。(最初は思いつきませんでした。)

解決策 c) shared_ptr を使用して配列を保持します。結局のところ、delete [] の代わりに delete を呼び出すため、カスタムのデリータを提供する必要があり、何らかの形で他の (構文) 問題が発生したため、その解決策を実行するのに 2 時間以上かかりました。

ヘッダーファイルでは次のようになります。

 template< typename T >
  struct
array_deleter
  {
      void
    operator ()( T const * p)
      { delete[] p; }
  };

class MemoryStressChunk
{
private:
    int chunkSizeInValues;
    std::shared_ptr< __int64 > data;
};

そしてコードファイルで:

data.reset(
    new __int64[chunkSizeInValues], 
    array_deleter< __int64 >() );

それを使用するには、もう一度取り出す必要があります。

__int64 *d = data.get();

次回はブーストバージョンの使用を強く検討するかもしれません. 私のマシンにはブーストがなかったので、オプションではありませんでした。

解決策 d) は、shared_ptr を含むクラスのベクトルを (配列の代わりに) ベクトルに使用することだと思います。私がcで楽しんだすべての後、私はそれを上にやりませんでした。:)

誰かがコードを見たい場合は、ここから入手できますhttp://andreas-reiff.de/wp-content/uploads/2011/01/Tool-MemTester.zip。バージョン a) にはおそらく memleak があることに注意してください (バージョン b) のように、クラスには shared_ptr を使用します)。

もう一度助けてくれてありがとう!

于 2011-01-24T14:25:18.790 に答える
0

shared_ptr少なくとも Boost ライブラリには、配列に相当するものがあります。という名前shared_arrayで、期待どおりに動作します。http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_array.htm?sess=8940ad57baa307d68cb2e7fd2939d2dbで仕様を確認してください。

于 2011-01-23T22:48:35.027 に答える