如何获取存储在unique_ptr中的指针的地址?

时间:2016-07-18 00:27:21

标签: c++ pointers unique-ptr

我正在尝试使用带有c ++的SDL2库,因此,某些函数需要一个指向SDL_Window或SDL_Renderer的双指针。我为一个SDL_Window设置了一些内存并将其赋予了一个如此独特的指针:

window = unique_ptr<SDL_Window, decltype(free) *>
    reinterpret_cast<SDL_Window *>(malloc(sizeof(SDL_Window))),
    free};

我使用以下网站作为指南:http://www.codeproject.com/Articles/820931/Using-std-unique-ptr-RAII-with-malloc-and-free

所以现在我需要一个指向存储在unique_ptr中的指针的指针,但是我很难这样做。 我尝试过这样的事情:

&window.get()
// or
&&(*window)
// or
&window
// and even
&(&(*(window.get())))

所有这些导致奇怪的编译器错误,例如一元'&amp;'所需的l值。对于第一个和最后一个案例完全可以理解的操作符。

更新 我现在还使用原始SDL_Window *来获取unique_ptr的地址和。我的一些代码片段(虽然脱离了上下文):

SDL_Window *window_ptr;
unique_ptr<SDL_Window> window;

window = unique_ptr<SDL_Window, decltype(SDL_DestroyWindow)> (
    window_ptr,
    SDL_DestroyWindow);

SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_SHOWN, &window_ptr, &renderer_ptr);

但现在,我正在运行此编译器错误:

/usr/include/c++/5/bits/unique_ptr.h:272:18: error: no match for ‘operator=’ 
(operand types are ‘std::unique_ptr<SDL_Window>::deleter_type 
{aka std::default_delete<SDL_Window>}’ and ‘void (*)(void*)’)
get_deleter() = std::forward<_Ep>(__u.get_deleter());

3 个答案:

答案 0 :(得分:5)

您无法获取存储在std::unique_ptr内的指针的地址。如果需要调用通过双指针返回指针的C代码,则需要将其传递给其他指针的地址,然后单独让std::unique_ptr取得该指针的所有权。如果std::unique_ptr允许你直接写入存储的指针,它将无法释放它以前持有的资源。

答案 1 :(得分:4)

通常情况下,当你在这些问题上纠缠不清时,你做错了是一个很大的线索。

例如,为什么需要SDL_Window**?例如,是因为您正在调用SDL_CreateWindowAndRenderer,一个创建窗口的函数吗?这与你已经创建了一个窗口对象并且似乎打算使用它的事实相冲突。

简要介绍一下API,意图似乎是SDL_Window个对象 创建的东西 - 它们是的东西库创建。

e.g。你真正想要做的就是lke

SDL_Window *window_;
SDL_Renderer *renderer_;
SDL_CreateWindowAndRenderer (/* ... */, &window_, &renderer_);
unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)>
    window(window_, &SDL_DestroyWindow);

答案 2 :(得分:-1)

unique_ptr是更简单的stl类之一-您可以重新实现它并添加一种方法来访问内部的指针。

以下代码是未定义的行为类别的丑陋骇客,但它确实有效(使用下面的代码段通过coliru在线编译器在GCC中进行了测试)

std::unique_ptr<myclass> uptr;
//Warning, undefined behavior!
myclass*& inside = *reinterpret_cast<myclass**>(&uptr);

要验证的小型测试程序:

#include <iostream>
#include <memory>

class myclass {
public:
    myclass() {
    }
    ~myclass() {
        std::cout << "It works!\n";
    }
};

int main()
{

    std::unique_ptr<myclass> uptr;
    //Warning, undefined behavior!
    myclass*& inside = *reinterpret_cast<myclass**>(&uptr);
    //Warning, undefined behavior!
    inside = new myclass();

    return 0;
}