I readily admit to still learning the finer notes of pointers in C/C++ and how they work but after doing some research, I just don't feel comfortable with the code below.
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen = std::make_shared<CDKSCREEN>(*initCDKScreen(newWin.get()));
Does the usage of raw pointers inside a std::shared_ptr
nullify any of the benefits you get from using smart pointers? Or is it just all the same either way? Thank you and I appreciate any answers to this post.
EDIT:
I did not realize the full purpose of the reset()
function but thank you to all who pointed this out to me. It seems I can also pass a custom destructor to std::shared_ptr
as well, like below:
std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()), destroyCDKScreen);
I think you want to save the pointer returned by initCDKScreen. In this case you don't have to use make_shared
. You should pass the pointer to the constructor or shared_ptr::reset(...)
:
std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()));
Since CDKSCREEN
should be destroyed by destroyCDKScreen(CDKSCREEN *screen)
and not with delete
, you should write something like this:
std::shared_ptr<CDKSCREEN> cdkScreen(initCDKScreen(newWin.get()), destroyCDKScreen);
or
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen.reset(initCDKScreen(newWin.get()), destroyCDKScreen);
I believe your example actually has a memory leak. Let's break it down:
CDKSCREEN* screen = initCDKScreen(newWin.get());
CDKSCREEN& screenRef = *screen;
// auto screenSharedPtr = std::make_shared<CDKSCREEN>(screenRef);
// this is basically:
CDKSCREEN* screen2 = new CDKSCREEN(screenRef);
shared_ptr<CDKSCREEN> screenSharedPtr (screen2);
As you can see, a copy is being made, but the original pointer isn't deleted. Oops.
If initCDKScreen
returns something that has to just be delete
d, then in this case I'd avoid the copy/move ctor and just .reset()
the smart pointer to it:
std::shared_ptr<CDKSCREEN> cdkScreen;
cdkScreen.reset(initCDKScreen(newWin.get()));
Actually, since it even has a constructor overload for that, go ahead and
std::shared_ptr<CDKSCREEN> cdkScreen { initCDKScreen(newWin.get()) };
If a custom destruction facility is needed, you can pass it as a 2nd parameter to the pointer. It makes perfect sense and smart pointer classes were designed for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With