Timmmm
Timmmm

Reputation: 96801

Convert vector to owned array without copying

A std::vector is more or less this:

class vector {
   T* array;
   size_t length;
   size_t capacity;
public:
   ...
}

Is it possible to extract the array object, taking ownership of it without copying any data? In other words, so that this is a valid program with no undefined behaviour or memory leaks.

int main() {
  vector<int> foo = {1, 2, 3};
  int* fooArray = foo.magical_extraction_method();
  delete[] fooArray;
}

To be clear, I am not looking for foo.data(), &foo[0] or similar. I want ownership of the underlying array.

Upvotes: 0

Views: 212

Answers (2)

ecatmur
ecatmur

Reputation: 157414

Yes, using unique_ptr with a custom deleter:

template<class T>
struct VectorDeleter {
    explicit constexpr VectorDeleter(std::vector<T> v) noexcept : v{std::move(v)} {};
    VectorDeleter(VectorDeleter&&) = default;
    VectorDeleter& operator=(VectorDeleter const&) = delete;
    std::vector<T> v;
    void operator()(T* p) {
        assert(p == v.data());
        v.clear();
    }
};

template<class T>
std::unique_ptr<T[], VectorDeleter<T>> release(std::vector<T>&& v) {
    auto const p = v.data();
    return std::unique_ptr<T[], VectorDeleter<T>>{p, VectorDeleter<T>{std::move(v)}};
}

Example.

There is nothing in the standard that can manage the memory of a std::vector other than the same std::vector. Mostly, this is because any number of elements from 0 to capacity() may have been constructed, and these elements only must be destructed before freeing the memory.

Upvotes: 1

eerorika
eerorika

Reputation: 238401

Is it possible to extract the array object, taking ownership of it

No, there is no standard way to extract ownership from a std::vector. Except into another vector (using move).

delete[] fooArray;

delete[] is only allowed on a pointer returned by new[]. A std::vector never owns such pointer.

Upvotes: 2

Related Questions