'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 |
