Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does this use of std::make_unique lead to non-unique pointers?

Suppose I have the following code in C++:

#include <memory>
#include <iostream>

struct Some {
        Some(int _a) : a(_a) {}
        int a;
};

int main() {
        Some some(5);

        std::unique_ptr<Some> p1 = std::make_unique<Some>(some);
        std::unique_ptr<Some> p2 = std::make_unique<Some>(some);

        std::cout << p1->a << " " << p2->a << std::endl;
        return 0;
}

As I understand, unique pointers are used to guarantee that resources are not shared. But in this case both p1 and p2 point to the same instance some.

Please unveil the situation.

like image 259
user3524337 Avatar asked Dec 01 '16 13:12

user3524337


People also ask

What is the use of std :: make_unique?

In this case, std::make_unique provides a "Basic Exception Safety" that the memory allocated and object created by new will never be orphaned no matter what.

Does make_unique initialize memory?

Yes, all the elements will be value initialized by std::make_unique. This is the initialization performed when a variable is constructed with an empty initializer.

When should we use unique pointer?

Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.

What is a unique pointer in C++?

(since C++11) std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.


3 Answers

They don't point to the same resource, they each point to a different copy of it. You can illustrate it by deleting the copy constructor to see the error:

#include <memory>
#include <iostream>

struct Some {
        Some(int _a) : a(_a) {}
        Some(Some const&) = delete;
        int a;
};

int main() {
        Some some(5);

        std::unique_ptr<Some> p1 = std::make_unique<Some>(some); //error here
        std::unique_ptr<Some> p2 = std::make_unique<Some>(some);

        std::cout << p1->a << " " << p2->a << std::endl;
        return 0;
}
like image 105
StoryTeller - Unslander Monica Avatar answered Oct 26 '22 21:10

StoryTeller - Unslander Monica


std::make_unique creates objects, calling constructor with specified arguments.

You passed Some& as parameter, and here copy constructor was invoked, and new object constructed.

So, p1 and p2 are 2 absolutely different pointers, but constructed from same object, using copy constructor

like image 37
Starl1ght Avatar answered Oct 26 '22 22:10

Starl1ght


both p1 and p2 point to the same instance some

No, they don't.

#include <memory>
#include <iostream>

struct Some {
        Some(int _a) : a(_a) {}
        int a;
};

int main() {
        Some some(5);

        std::unique_ptr<Some> p1 = std::make_unique<Some>(some);
        std::unique_ptr<Some> p2 = std::make_unique<Some>(some);

        std::cout << p1->a << " " << p2->a << std::endl;
        p1->a = 42;
        std::cout << p1->a << " " << p2->a << std::endl;
        return 0;
}

output:

5 5
42 5
like image 45
milleniumbug Avatar answered Oct 26 '22 21:10

milleniumbug