2016-11-23 9 views
2

まず、私の動機は、計算カーネルのようなCの上で効率的なメモリ管理を行うことです。そして、私はここで練習p_dataunique_ptrと適切なコンテナを使用してメモリ管理を行う

// my data container 
typedef std::unique_ptr<double> my_type; 
std::vector<my_type> my_storage; 

// when I need some memory for computation kernel 
my_storage.push_back(my_type()); 
my_storage.back.reset(new double[some_length]); 

// get pointer to do computational stuff 
double *p_data=my_storage.back.get(); 

下記の注意事項は、ドメインの問題に応じて、それぞれに割り当てられた配列のインデックスを作成するには、いくつかの他の容器(例えばマップ)に格納することができるように私のコードが見え、 std::unique_ptrstd::vectorを使用しようとしましたそれにもかかわらず、私の主な質問は

  1. ここにはstd::vectorがいいですか? std::list/setのような他の容器はどうですか?

  2. 割り当て方法に根本的な問題はありますか?私はいくつかの操作のためにp_dataを使用した後

  3. は仮定し、今私は生のポインタp_dataが指すメモリチャンクを解放したい、ここでのベストプラクティスは何ですか?

+1

あなたは 'p_data'が異なるコンテナ間で共有されることが予想され、あなたの代わりに'のstd :: shared_ptr'を使用することができ、その後、あなたはまったく生のポインタを使用しない場合。 – Mine

+0

'std :: unique_ptr '、 'new double []'を使い、この不一致を避けるために 'std :: make_unique'を好むならば。 – Jarod42

+0

@Mine:これは明らかに不明な問題のOP仕様に従って、リソースの無駄になることがあります。 – Jack

答えて

1

まず第一に、あなたは専門std::unque_ptr<T[]>を使用する必要があるか、あなたはシンプルdeleteが、メモリの解放にdelete []を取得することはありません配列を割り当てている場合。

std::vectorは、別のものを使用する明白な理由がない限り、適切な選択です。あなたは、コンテナ内の多くの要素を移動しようとしている場合たとえば、その後std::listは、周りのものをシフトするために、より良い(より少ないmemmove操作を行うことができます。

メモリを管理する方法についてはut​​lizationのパターンに主に依存します。my_storageがある場合保存生のポインタを管理することをメインにすべての責任(unique_ptrが所有権を表現するので、あなたの仕様では、それは、ある)それがメモリを解放することができる唯一のことを意味します。my_storage[i].reset()を呼び出すことで簡単に行うことができた。

マインド他のコレクション内のオブジェクトは、メモリが解放された場合、ポインタがつぶれてしまいます。例えば、

using my_type = std::unique_ptr<double[]>; 
using my_storage = std::vector<my_type>; 

my_storage data; 
data.push_back(my_type(new double[100])); 

std::vector<double*> rawData; 
rawData.push_back(data[0].get()); 

data.clear(); // delete [] is called on array and memory is released 
*rawData[0] = 1.2; // accessing a dangling pointer -> bad 

dataは、その後、問題がない最後で解放された場合、これは、メモリがまだ有効であるならば、少なくともあなたがチェックすることができるだろうように、そうでなければ、std::unique_ptrへのconstの参照を格納することができ、問題やない可能性があり例えば:

using my_type = std::unique_ptr<double[]>; 
using my_managed_type = std::reference_wrapper<const my_type>; 
std::vector<my_managed_type> rawData; 
+0

この場合、ベクトルはshared_ptrを格納します。したがって、おそらくstd :: listはポインタ(メモリ)を入れ替えてもあまり効果がありませんか? – lorniper

0

、任意のSTLコンテナとstd::unique_ptrを使用してstd::vectorを含め、一般的には大丈夫です。しかし、あなたはstd::unique_ptr正しい方法を使用していません(アレイの特殊バージョンを使用していない)ので、back.reset()をまったく使用する必要はありません。代わりにこれを試してみてください:

// my data container 
typedef std::unique_ptr<double[]> my_type; 
// or: using my_type = std::unique_ptr<double[]>; 

std::vector<my_type> my_storage; 

my_type ptr(new double[some_length]); 
my_storage.push_back(std::move(ptr)); 
// or: my_storage.push_back(my_type(new double[some_length])); 
// or: my_storage.emplace_back(new double[some_length]); 
関連する問題