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

How do a get the address of the pointer stored in a unique_ptr?

本文关键字:ptr unique 指针 地址 何获取 获取 存储      更新时间:2023-10-16

我正在尝试将 SDL2 库与 c++ 一起使用,因此,某些函数需要指向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())))

所有这些都导致了奇怪的编译器错误,例如一元"&"运算符需要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());

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

通常,当你纠结于这样的问题时,这是一个巨大的线索,表明你做错了。

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

简要浏览一下 API,其意图似乎是SDL_Window对象不是创建的东西 - 它们是创建的东西。

例如,你真正想做的事情是 lke

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

12/2020 之后访问此问题的任何人,C++20 现在包含一个重载流插入运算符<<用于唯一指针(以及重载运算符 <=> 并删除了运算符! 请确保在命令行、生成文件中指定 -std=c++20,或在 IDE 中使用 C++20。

unique_ptr是

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

下面的代码是一个未定义的行为类别丑陋的黑客,但它实际上有效(在GCC中使用coliru在线编译器进行了测试,代码片段如下):

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