I'm relatively new to cpp, and am learning about smart points. I'm wondering the following:
Why is constructing an std::unique_ptr
with an lvalue
allowed?
Wouldn't it be safer to only allow the construction of an std::unique_ptr
with rvalues to avoid evil things?
std::unique_ptr<int> createInt() {
int* a = new int(99);
std::unique_ptr<int> foo(a);
delete a;
return foo;
}
I realize you'd have to be crazy to write something like that but I'd be nice to have the compiler yell at you for it. So I'm left wondering, why is lvalue initialization of unique_ptr a thing?
EDIT: User @aler egal put my thoughts more elagantly:
"In principle, you could have a constructor
unique_ptr<int>(int*&& ptr)
which assumes ownership of ptr and then sets it tonull
. That would prevent a use-after-free in this specific example (because you'd be forced tostd::move(a)
and because calling delete on a null pointer has no effect) but it would be a very strange anti-pattern."
This is a classic example of what a dangling pointer is! In contrast to what smart pointers may seem, they are simply wrappers over normal (raw) pointers, which can manage memory on their own and give you some added functionalities.
Consider the following example:
int* someFunc() {
int* ptr;
int* ptr2 = ptr;
delete ptr;
return ptr2;
}
This is what you are essentially doing.
They have been made such that they can be used instead of raw owning pointers at all times; meaning, they can be dangled too! So, if they are not allowed lvalue initialisation, that's one use case where you can't use a smart pointer, although I agree, this is one case where you are not to use either!
The above code with smart pointers will be exactly what you tried.
Now, C++ leaves logic to you... entirely. If you want to shoot yourself in the foot, go ahead, C++ won't bark. C++ does not check for memory usage and buffer overflows and access of deleted memory. Simply speaking, it's the job of a C++ programmer and if he/she wants to shoot himself/herself in the foot, he/she's free to do so!
Also, it is usually recommended to use std::make_ptr()
over the ctor, as the former is exceptions enabled
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