7

有没有办法将 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,double data)。然而,这会导致少量内存泄漏(用于处理 v 的容量、大小等的数据结构......当然不是数据本身)。

有没有可能不漏?

4

5 回答 5

7

一个简单的解决方法是将向量与您拥有的向量交换:

vector<double> myown;

vector<double> someoneelses = foo();

std::swap( myown, someoneelses );

一个更难但可能更好的方法是为向量编写自己的分配器,并让它从你维护的池中分配。没有亲身经历,但也不算太复杂。

于 2009-11-13T14:47:12.607 回答
6

使用 std::vector 的目的是不必担心其中的数据:

  • 在您的应用程序中始终保留您的矢量;
  • 通过 const-ref 将其传递给其他函数(以避免不必要的复制);
  • 并提供期望指向 T 的指针的函数&v[0]

如果你真的不想保留你的向量,你将不得不复制你的数据——你不能转移所有权,因为std::vector保证它会在超出范围时破坏其内容。在这种情况下,使用std::copy()算法。

于 2009-11-13T14:52:47.300 回答
1

如果您的向量包含值,您只能复制它们(当您调用 std::copy、std::swap 等时会发生这种情况)。如果您将非原始对象保存在向量中并且不想复制它们(并在另一个数据结构中使用),请考虑存储指针

于 2009-11-13T14:51:39.410 回答
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;
}
于 2009-11-13T14:43:55.430 回答
-2

由于您不想在容器之间复制数据,而是想在容器之间转移数据的所有权,因此我建议使用智能指针容器,如下所示。

void f()
{
    std::vector<boost::shared_ptr<double> > doubles;
    InitVector(doubles);

    std::vector<boost::shared_ptr<double> > newDoubles(doubles);
}

你真的不能在标准容器之间转移数据的所有权而不复制它,因为标准容器总是复制它们封装的数据。如果您想最小化复制昂贵对象的开销,那么使用引用计数智能指针来包装昂贵的数据结构是一个好主意。 boost::shared_ptr适合这项任务,因为制作它的副本相当便宜。

于 2009-11-13T20:32:46.403 回答