2016-11-23 50 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]);