C++:将 C 样式数组包装成 unique_ptr 导致 "double free or corruption"

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

我有一个 C 函数,returns 我有一个 C 样式数组。我想把它包装成更多 C++ 风格的代码,这样我就不必手动管理它的生命周期。所以,我这样定义我的包装器:

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

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

但是,当如下使用时:

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

我明白了

double free or corruption (out)
Aborted

据我了解,arr唯一被销毁的地方应该是std::unique_ptr的析构函数,它在其父Wrapper被销毁后立即被销毁。我在这里错过了什么?

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

这个变量有自动存储期限。它将在声明范围的末尾销毁。

您将指向自动数组第一个元素的指针传递给构造函数。构造函数初始化唯一指针成员以指向自动数组。在析构函数中,唯一指针被销毁,其析构函数在存储的指针上调用 delete[]。在不是通过数组的 new 获取的任何指针上调用 delete[] 会导致未定义的行为。本例中的指针指向一个未被 new[] 获取的自动数组,因此程序的行为未定义。

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

那不是arr可以销毁的地方,因为arr是一个自动变量。

结论:(几乎)永远不会在智能指针中存储指向任何变量的指针。只存储指向动态对象的指针,其释放函数与智能指针的删除器匹配。尽可能使用 std::make_unique(和相关函数)创建智能指针,以避免将来犯这种错误。


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

这两件事互不相容。为了使用智能指针,您必须知道某些东西是如何分配的,否则您无法知道与智能指针一起使用的相应删除器。

I have a C function

C API 通常有一对分配和释放函数,或者他们使用 malloc 并希望你释放。相关细节应该在API.

的文档中