Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating shared_ptr from raw pointer

Tags:

c++

I have a pointer to an object. I would like to store it in two containers which both have the ownership. So I think I would be good to make it a shared_ptr of C++0x. How could I convert a raw pointer to a shared_pointer?

typedef unordered_map<string, shared_ptr<classA>>MAP1; MAP1 map1; classA* obj = new classA(); map1[ID] = how could I store obj in map1?? 

Thanks

like image 642
Leslieg Avatar asked Jan 12 '11 04:01

Leslieg


People also ask

How can a weak_ptr be turned into a shared_ptr?

The weak_ptr class template stores a "weak reference" to an object that's already managed by a shared_ptr. To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr constructor or the member function lock.

Is shared_ptr a smart pointer?

The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.

Can shared_ptr be Nullptr?

A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .

What does shared_ptr get () do?

A shared_ptr may share ownership of an object while storing a pointer to another object. get() returns the stored pointer, not the managed pointer.


2 Answers

You need to make sure you don't initialize both shared_ptr objects with the same raw pointer, or it will be deleted twice. A better (but still bad) way to do it:

classA* raw_ptr = new classA; shared_ptr<classA> my_ptr(raw_ptr);  // or shared_ptr<classA> my_ptr = raw_ptr;  // ...  shared_ptr<classA> other_ptr(my_ptr); // or shared_ptr<classA> other_ptr = my_ptr; // WRONG: shared_ptr<classA> other_ptr(raw_ptr); // ALSO WRONG: shared_ptr<classA> other_ptr = raw_ptr; 

WARNING: the above code shows bad practice! raw_ptr simply should not exist as a variable. If you directly initialize your smart pointers with the result of new, you reduce your risk of accidentally initializing other smart pointers incorrectly. What you should do is:

shared_ptr<classA> my_ptr(new classA);  shared_ptr<classA> other_ptr(my_ptr); 

What's nice is that the code is more concise as well.

EDIT

I should probably elaborate on how it would work with a map. If you had a raw pointer and two maps, you could do something similar to what I showed above.

unordered_map<string, shared_ptr<classA> > my_map; unordered_map<string, shared_ptr<classA> > that_guys_map;  shared_ptr<classA> my_ptr(new classA);  my_map.insert(make_pair("oi", my_ptr)); that_guys_map.insert(make_pair("oi", my_ptr)); // or my_map["oi"].reset(my_ptr); // or my_map["oi"] = my_ptr; // so many choices! 
like image 170
Dawson Avatar answered Oct 22 '22 12:10

Dawson


You can use a variety of ways, but reset() would be good:

map1[ID].reset(obj); 

And to address the issue of having two maps refer to the same shared_ptr, we can have:

map2[ID] = map1[ID]; 

Note that the trick in general to avoid a double delete is to try to avoid raw pointers at all. Hence avoid:

classA* obj = new classA(); map1[ID].reset(obj); 

but instead put the new heap object straight into a shared_ptr.

like image 24
Keith Avatar answered Oct 22 '22 12:10

Keith