English 中文(简体)
preventing data from being freed when vector goes out of scope
原标题:

Is there a way to transfer ownership of the data contained in a std::vector (pointed to by, say T*data) into another construct, preventing having "data" become a dangling pointer after the vector goes out of scope?

EDIT: I DON T WANT TO COPY THE DATA (which would be an easy but ineffective solution).

Specifically, I d like to have something like:

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
}

The only thing that comes to my mind to emulate this is:

{
    vector<double>*v=new vector<double>();
    //grow *v...
    data=(*v)[0];
}

and then data will later either be freed or (in my case) used as mxSetData(mxArrayA,doubledata). However this results in a small memory leak (data struct for handling v s capacity, size, etc... but not the data itself of course).

Is it possible without leaking ?

问题回答

A simple workaround would be swapping the vector with one you own:

vector<double> myown;

vector<double> someoneelses = foo();

std::swap( myown, someoneelses );

A tougher but maybe better approach is write your own allocator for the vector, and let it allocate out of a pool you maintain. No personal experience, but it s not too complicated.

The point of using a std::vector is not to have to worry about the data in it:

  • Keep your vector all along your application;
  • Pass it by const-ref to other functions (to avoid unnecessary copies);
  • And feed functions expecting a pointer-to-T with &v[0].

If you really don t want to keep your vector, you will have to copy your data -- you can t transfer ownership because std::vector guarantees it will destroy its content when going out-of-scope. In that case, use the std::copy() algorithm.

If your vector contains values you can only copy them (which happens when you call std::copy, std::swap, etc.). If you keep non-primitive objects in a vector and don t want to copy them (and use in another data structure), consider storing pointers

Does something like this work for you?

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;
}

Since you don t want to copy data between containers, but want to transfer ownership of data between containers, I suggest using a container of smart pointers as follows.

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

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

You really can t transfer ownership of data between standard containers without making a copy of it, since standard containers always copy the data they encapsulate. If you want to minimize the overhead of copying expensive objects, then it is a good idea to use a reference-counted smart pointer to wrap your expensive data structure. boost::shared_ptr is suitable for this task since it is fairly cheap to make a copy of it.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签