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

I'm trying to use the SDL2 library with c++ and as such, some of the functions need a double pointer to an SDL_Window or SDL_Renderer. I've malloc'ed some memory for an SDL_Window and gave that to a unique pointer like so:

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

and I used the following site as a guide for that: http://www.codeproject.com/Articles/820931/Using-std-unique-ptr-RAII-with-malloc-and-free

So now I need to get a pointer to the pointer stored inside the unique_ptr but I'm having trouble doing so. I've tried things like:

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

All of these resulted in strange compiler errors like an l-value being required for the unary '&' operator which is entirely understandable for the first and last cases.

Updates I now also use a raw SDL_Window * to get the address of and to give to unique_ptr. Some of my code snippets (out of context though):

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

But now, I'm running this compiler error:

/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());


Solution 1:[1]

You cannot get the address of the pointer stored inside a std::unique_ptr. If you need to call C code that returns a pointer through a double pointer, you need to pass it the address of some other pointer and then separately have the std::unique_ptr take ownership of that pointer. If the std::unique_ptr allowed you to write directly to the stored pointer, it would have no way of releasing the resource it previously held.

Solution 2:[2]

Often, when you get tangled up in questions like these, it's a huge clue that you're doing it wrong.

For example, why do you need a SDL_Window**? Is it, for example, because you are calling SDL_CreateWindowAndRenderer, a function that creates a window? That conflicts with the fact you've already created a window object and seemingly intend to use that.

Skimming briefly at the API, the intent seems to be that SDL_Window objects are not things that you create — they are things that the library creates.

e.g. what you really want to do is something lke

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

Solution 3:[3]

For anyone visiting this question after 12/2020, C++20 now includes an overloaded stream insertion operator<< for unique pointers ( as well as the overloaded operator<=> and it removed the operator!= ). make sure you are specifying -std=c++20 in the command line, makefile, or using c++20 in your IDE.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Brian Bi
Solution 2
Solution 3 Liam White