【问题标题】:Get array of raw pointers from array of std::unique_ptr从 std::unique_ptr 数组中获取原始指针数组
【发布时间】:2018-07-26 03:34:17
【问题描述】:

我有一个库函数,它需要一个包含四个指针的数组作为参数:f(unsigned char* data[4]),我的代码中有一个智能指针数组:std::unique_ptr<unsigned char> myArray[4]

有没有办法在这个库函数中使用智能指针?

我已经尝试过了,但它给了我一个段错误:f(reinterpret_cast<unsigned char **>(myArray[0].get()));

【问题讨论】:

  • 将指针复制到一个由四个指针组成的数组。

标签: c++ arrays smart-pointers


【解决方案1】:
std::array<unsigned char* , 4> arr = { myArray[0].get(),myArray[1].get(),myArray[2].get(),myArray[3].get() };

通过arr.data()

【讨论】:

    【解决方案2】:

    你的演员表是错误的。您正在转换存储在第一个数组元素中的 unsigned char * 指针。您需要转换元素本身的地址:

    f(reinterpret_cast<unsigned char **>(&myArray[0]));
    

    或者甚至转换数组本身:

    using puchar = unsigned char *;
    f(reinterpret_cast<puchar(&)[4]>(myArray));
    

    但是,这些只是因为std::unique_ptr 被设计为没有比原始指针更多的存储开销。但是使用这些解决方案是未定义的行为。正确的解决方案是简单地将指针复制到另一个数组,例如:

    unsigned char* myArrayOfPtrs[] = { myArray[0].get(), myArray[1].get(), myArray[2].get(), myArray[3].get() };
    f(myArrayOfPtrs);
    

    或者:

    unsigned char* myArrayOfPtrs[4];
    for (int i = 0; i < 4; ++i) {
        myArrayOfPtrs[i] = myArray[i].get();
    }
    f(myArrayOfPtrs);
    

    或者:

    #include <algorithm>
    
    unsigned char* myArrayOfPtrs[4];
    std::transform(std::begin(myArray), std::end(myArray), std::begin(myArrayOfPtrs),
        [](auto &p) { return p.get(); }
    );
    f(myArrayOfPtrs);
    

    【讨论】:

      【解决方案3】:

      如果您确定您的unique_ptr 不会超出范围并希望它保留关联指针的所有权,您可以在数组中的每个指针上使用char* a[] = {myArray[0].get(), myArray[1].get(), myArray[2].get(), myArray[3].get()} 并创建一个常规指针数组。

      unique_pointers 保留char* 资源的所有权,如果它们超出范围,unique_ptr 析构函数将释放指针。

      如果您想释放所有权,您可以在 unique_ptrs 上使用 release() 方法,这将允许您安全地转换为常规指针并确保超出范围的 unique_ptr 不会解除分配底层 char* 资源。

      release():https://en.cppreference.com/w/cpp/memory/unique_ptr/release

      get():https://en.cppreference.com/w/cpp/memory/unique_ptr/get

      【讨论】:

        猜你喜欢
        • 2019-11-07
        • 2017-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-18
        • 2021-04-14
        • 2011-09-23
        • 1970-01-01
        相关资源
        最近更新 更多