简体   繁体   中英

C++: Wrapping C style array into unique_ptr leads to "double free or corruption"

I have a C function that returns me a C style array. I would like wrap this into more C++ style code, so I don't have to manage its lifetime manually. So, I defined my wrapper as such:

template <typename T>
class Wrapper {
public:
    std::unique_ptr<T[]> data;

    explicit Wrapper(T data[]) : data(data) {}
};

However, when using it as follows:

int main(int argc, char *argv[])
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8}; // simulate my C style function
    Wrapper<int> wrapped(arr);
    return 0;
}

I get

double free or corruption (out)
Aborted

As far as I understand, the only place where arr is destroyed, should be the destructor of std::unique_ptr , which is destroyed as soon as its parent Wrapper is destroyed. What am I missing here?

 int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};

This variable has automatic storage duration. It will be destroyed at the end of the scope where it is declared.

You pass a pointer to the first element of the automatic array into the constructor. The constructor initialises the unique pointer member to point to the automatic array. In the destructor, the unique pointer is destroyed and its destructor invokes delete[] on the stored pointer. Invoking delete[] on any pointer that was not acquired through new of an array results in undefined behaviour. The pointer in this case points to an automatic array which was not acquired by new[] , and therefore the behaviour of the program is undefined.

As far as I understand, the only place where arr is destroyed, should be the destructor of std::unique_ptr

That is not where arr may be destroyed, because arr is an automatic variable.

In conclusion: (Almost) never store pointers to any variables in smart pointers. Only store pointers to dynamic objects, whose deallocation function matches the deleter of the smart pointer. Prefer to create smart pointers using std::make_unique (and related functions) when possible to avoid making this mistake in the future.


I go through them and wrap them into unique_ptr, but I'm not sure how they were allocated.

These two things are not compatible with one another. In order to use a smart pointer, you must know how something is allocated because otherwise you cannot know the corresponding deleter to use with the smart pointer.

I have a C function

C API usually have a pair of allocation and deallocation functions, or they use malloc and expect you to free. The relevant details should be in the documentation of the API.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM