2016-11-23 48 views
2

首先,我的動機是做高效的內存管理像計算內核是C的頂部。我試圖用std::unique_ptrstd::vector,我的代碼看起來像下面使用的unique_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(); 

注意這裏在實踐中p_data可以存儲在其他一些容器(例如地圖)以索引每個分配的陣列根據域名問題儘管如此,我的主要問題是

  1. 這裏是std::vector一個好的選擇嗎?什麼樣std::list/set其他容器?

  2. 是否與我的分配方法的根本問題?

  3. 假設我用p_data對於某些操作後,現在我想以釋放原始指針p_data指向的內存塊,什麼是最好的做法嗎?

+1

如果你'p_data'預計將在不同的容器之間共享,你可以使用'的std :: shared_ptr'代替,然後就完全不使用原始指針。 – Mine

+0

'的std ::的unique_ptr ',如果你使用'新雙[]'和'喜歡的std :: make_unique'避免這種不匹配。 – Jarod42

+0

@Mine:根據目前尚不清楚的OP規範,這可能完全是浪費資源。 – Jack

回答

1

首先,如果你分配你需要使用專門std::unque_ptr<T[]>一個數組,否則將無法在內存釋放,但一個簡單的delete得到delete []

std::vector是一個不錯的選擇,除非你有任何明確的理由使用不同的東西。例如,如果你要移動的容器內的許多元素則std::list可以表現得更好(少memmove操作遊移的事情。

關於如何管理內存則主要依賴utlization的格局。如果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這樣至少你可以檢查內存是否仍然有效例如:

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

使用std::unique_ptr與任何STL容器,包括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]);