C++ 使用唯一的ptr和适当的容器进行内存管理
首先,我的动机是在类似C的计算内核上进行有效的内存管理。我尝试使用C++ 使用唯一的ptr和适当的容器进行内存管理,c++,c++11,memory-management,containers,smart-pointers,C++,C++11,Memory Management,Containers,Smart Pointers,首先,我的动机是在类似C的计算内核上进行有效的内存管理。我尝试使用std::unique\u ptr和std::vector,我的代码如下所示 // 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
std::unique\u ptr
和std::vector
,我的代码如下所示
// 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();
//我的数据容器
typedef std::唯一的\u ptr我的\u类型;
std::向量my_存储;
//当我需要一些计算内核的内存时
my_storage.push_back(my_type());
my_storage.back.reset(新的双精度[某些长度]);
//获取指针来执行计算任务
double*p_data=my_storage.back.get();
请注意,在实践中,p_数据可以存储在其他容器中(例如map),以便根据域问题对每个分配的数组进行索引,然而,我的主要问题是
std::vector
一个不错的选择?其他容器如std::list
/set
首先,如果要分配数组,则需要使用专用化
std::unique\u ptr
,否则在释放内存时不会得到delete[]
,而是得到一个简单的delete
std::vector
是一个不错的选择,除非您有明确的理由使用不同的东西。例如,如果要在容器中移动多个元素,则std::list
可以执行更好的操作(减少memmove
操作来移动内容)
关于如何管理内存,这主要取决于使用模式。如果my_storage
主要负责所有事情(在您的规范中,它是唯一的,因为unique\u 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
通常,对任何STL容器(包括
std::vector
)使用std::unique\u ptr
)都可以。但是,您没有以正确的方式使用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]);
//我的数据容器
typedef std::唯一的\u ptr我的\u类型;
//或者:使用my_type=std::unique_ptr;
std::向量my_存储;
my_type ptr(新双精度[某些长度]);
my_storage.push_back(std::move(ptr));
//或者:my_storage.push_back(my_type(新的双精度[some_length]);
//或者:我的存储。放置回(新的双[一些长度]);
如果希望在不同容器之间共享p_数据
,则可以使用std::shared_ptr
,然后根本不使用原始指针。std::unique_ptr
,如果使用new double[]
,并且更喜欢std::make_unique()
以避免这种不匹配。@我的:根据问题的OP规范,这可能完全是浪费资源,这是不清楚的。@Jarod42:std::make_unique()
不在C++11中,它是在C++14中添加的。@Mine在不同的容器之间共享的?在我的例子中,p_数据存储在一个映射中,其中值是地址,所以我猜在我的例子中,它的所有权是唯一的。也许您可以给出一些具体的例子?在这种情况下,vector存储共享的_ptr,所以在这里,即使我们可以交换指针(内存),std::list也不会有太大的好处?
// 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]);