有没有办法将std :: vector(由T *数据指向)中包含的数据的所有权转移到另一个构造中,防止在向量超出范围后“data”成为悬空指针?
编辑:我不想复制数据(这将是一个简单但无效的解决方案)。
具体来说,我希望有类似的东西:
template<typename T>
T* transfer_ownership(vector<T>&v){
T*data=&v[0];
v.clear();
...//<--I'd like to make v's capacity 0 without freeing data
}
int main(){
T*data=NULL;
{
vector<double>v;
...//grow v dynamically
data=transfer_ownership<double>(v);
}
...//do something useful with data (user responsible for freeing it later)
// for example mxSetData(mxArray*A,double*data) from matlab's C interface
}
我想到的唯一能够效仿的是:
{
vector<double>*v=new vector<double>();
//grow *v...
data=(*v)[0];
}
然后数据将被释放或(在我的情况下)用作mxSetData(mxArray A,双数据)。然而,这会导致内存泄漏(用于处理v容量,大小等的数据结构......但当然不是数据本身)。
是否可以不泄漏?
答案 0 :(得分:6)
一个简单的解决方法是使用您拥有的向量交换向量:
vector<double> myown;
vector<double> someoneelses = foo();
std::swap( myown, someoneelses );
更难但可能更好的方法是为向量编写自己的分配器,并让它从您维护的池中分配。没有个人经验,但也不是太复杂。
答案 1 :(得分:5)
使用std :: vector的重点是不必担心其中的数据:
&v[0]
的指针。如果你真的不想保留你的矢量,你将不得不复制你的数据 - 你不能转移所有权,因为std::vector
保证它在超出范围时会破坏它的内容。在这种情况下,请使用std::copy()
算法。
答案 2 :(得分:1)
如果你的向量包含值,你只能复制它们(当你调用std :: copy,std :: swap等时会发生这种情况)。如果将非原始对象保留在向量中并且不想复制它们(并在另一个数据结构中使用),请考虑存储指针
答案 3 :(得分:0)
这样的事情对你有用吗?
int main()
{
double *data = 0;
{
vector<double> foo;
// insert some elements to foo
data = new double[foo.size()];
std::copy(foo.begin(), foo.end(), &data[0]);
}
// Pass data to Matlab function.
delete [] data;
return 0;
}
答案 4 :(得分:-2)
由于您不想在容器之间复制数据,但想要在容器之间传输数据的所有权,我建议使用智能指针容器,如下所示。
void f()
{
std::vector<boost::shared_ptr<double> > doubles;
InitVector(doubles);
std::vector<boost::shared_ptr<double> > newDoubles(doubles);
}
由于标准容器始终复制它们封装的数据,因此您无法在不复制标准容器的情况下转移标准容器之间的数据所有权。如果您想最大限度地减少复制昂贵对象的开销,那么最好使用引用计数的智能指针来包装昂贵的数据结构。 boost::shared_ptr
适用于此任务,因为制作副本相当便宜。