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.
Yes, the vector 's destructor will be called, and this will clear its contents.
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 i have to somehow delete the vector to free memory? No. The std::vector will automatically de-allocate the memory it uses.
vector::clear() clear() function is used to remove all the elements of the vector container, thus making it size 0.
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With