Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unique_ptr constructor with rvalue deleter returns null?

Here's a code snippet I'm using to understand the behavior of std::unique_ptr:

std::default_delete<int> d;
std::unique_ptr<int> u1;
std::unique_ptr<int> u2 (nullptr);
std::unique_ptr<int> u3 (new int);
std::unique_ptr<int> u4 (new int, d);
std::unique_ptr<int> u5 (new int, std::default_delete<int>());
std::unique_ptr<int> u6 (std::move(u5));
std::unique_ptr<int> u7 (std::move(u6));
std::unique_ptr<int> u8 (std::auto_ptr<int>(new int));

std::cout << "u1: " << (u1?"not null":"null") << '\n';
std::cout << "u2: " << (u2?"not null":"null") << '\n';
std::cout << "u3: " << (u3?"not null":"null") << '\n';
std::cout << "u4: " << (u4?"not null":"null") << '\n';
std::cout << "u5: " << (u5?"not null":"null") << '\n';
std::cout << "u6: " << (u6?"not null":"null") << '\n';
std::cout << "u7: " << (u7?"not null":"null") << '\n';
std::cout << "u8: " << (u8?"not null":"null") << '\n';

Can somebody explain why null is printed for u5 and u6, but not for u7? Thanks in advance!

like image 850
Andy Avatar asked Jul 02 '26 07:07

Andy


1 Answers

As Phil1970 pointed out in his comment a std::unique_pointer instance becomes (equivalent to) nullptr after it is assigned to another instance (using std::move as seen in your code example). Actually this is what std::unique_ptr is made for. It is, well, unique.

Now consider this piece of code:

#include <memory>
#include <iostream>

int main()
{
    std::default_delete<int> d;
    std::unique_ptr<int> u1;
    std::cout << "u1: " << (u1 ? "not null" : "null") << '\n';

    std::unique_ptr<int> u2(nullptr);
    std::cout << "u2: " << (u2 ? "not null" : "null") << '\n';

    std::unique_ptr<int> u3(new int);
    std::cout << "u3: " << (u3 ? "not null" : "null") << '\n';

    std::unique_ptr<int> u4(new int, d);
    std::cout << "u4: " << (u4 ? "not null" : "null") << '\n';

    std::unique_ptr<int> u5(new int, std::default_delete<int>());
    std::cout << "u5: " << (u5 ? "not null" : "null") << '\n';

    std::unique_ptr<int> u6(std::move(u5));
    std::cout << "u6: " << (u6 ? "not null" : "null") << '\n';

    std::unique_ptr<int> u7(std::move(u6));
    std::cout << "u7: " << (u7 ? "not null" : "null") << '\n';
}

When executed you see that u5 and u6 are "not null" immediately after instantiation.

like image 151
TobiMcNamobi Avatar answered Jul 03 '26 20:07

TobiMcNamobi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!