Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deny std::vector from deleting its data

Tags:

c++

c++11

vector

I have the following case:

T* get_somthing(){
    std::vector<T> vec; //T is trivally-copyable
    //fill vec
    T* temp = new T[vec.size()];
    memcpy(temp, vec.data(), vec.size() * sizeof(T));
    return temp;
}

I want to get rid of the copy process by returning the std::vector::data directly like this:

T* get_somthing(){
    std::vector<T> vec; //T is trivally-copyable
    //fill vec
    return temp.data();
}

However, that is wrong since the data is going to be deleted when vec destructor is called.

So, how can I prevent vec from delete its data? In other word I want some kind of move-idiiom from std::vector to C++ Raw Dynamic Array.

P.S. Changing the design is not an option. Using the std::vector there is mandatory. Returning a pointer to array is also mandatory. Becauese It is a wrapper between two modules. One need vector the other need pointer.

like image 592
Humam Helfawi Avatar asked Apr 15 '16 09:04

Humam Helfawi


People also ask

Does deleting a vector delete its contents?

Yes, the vector 's destructor will be called, and this will clear its contents.

Does std::vector call Delete?

std::vector does call the destructor of every element it contains when clear() is called. In your particular case, it destroys the pointer but the objects remain.

Do vectors automatically delete?

do i have to somehow delete the vector to free memory? No. The std::vector will automatically de-allocate the memory it uses.

What does vector Clear () do?

vector::clear() clear() function is used to remove all the elements of the vector container, thus making it size 0.


2 Answers

P.S. Changing the design is not an option. Using the std::vector there is mandatory. Returning a pointer to array is also mandatory.

Changing the design is your best option. I recommend reconsidering this stance.

There is (currently) no way to "steal" the buffer of a vector, so given the (silly††) limitations stated in the question, copying is the way to go.

† Tomasz Lewowski linked a proposal that would change this if it is included in a future standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4359.pdf (Edit: as pointed out, it was rejected from c++17)

†† Silly until justified by concrete requirements.


It is a wrapper between two modules. One need vector the other need pointer.

Presumably, the other interface that needs the pointer, delegates the destruction of the buffer to the caller, possibly using some sort of call back like void delete_somthing(T*). Taking ownership without giving it back would have been very bad design, in my opinion.

In case you do have control of the destruction, you can store the vector in a map, and erase the vector, when the pointer is passed for destruction:

std::unordered_map<T*, std::vector<T>> storage;

T* get_somthing(){
    std::vector<T> vec; //T is trivally-copyable
    //fill vec
    T* ptr = vec.data();
    storage[ptr] = std::move(vec);
    return ptr;
}

void delete_somthing(T* ptr){
    storage.erase(ptr);
}
like image 85
eerorika Avatar answered Oct 06 '22 18:10

eerorika


In C++11 there is no option to release the buffer from the vector.

Such extension to standard was proposed to C++17: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4359.pdf but, as T.C. pointed out, it was rejected: https://issues.isocpp.org/show_bug.cgi?id=81

So no luck in the standard for that. Also a related question was posted that is already answered and explains the same problem: Destroy std::vector without releasing memory

If you are able to mess with either of these libraries you can try custom allocators or other weird stuff (like binding yourself to internal implementation of library and messing with private vector data), but really, don't.

like image 43
Tomasz Lewowski Avatar answered Oct 06 '22 18:10

Tomasz Lewowski