Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign the address of an existing object to a smart pointer?

#include <memory>  class bar{};  void foo(bar &object){     std::unique_ptr<bar> pointer = &object; } 

I want to assign an address of the object to the pointer. The above code obviously wont compile, because the right side of the assignment operator needs to be a std::unique_ptr. I've already tried this:

pointer = std::make_unique<bar>(object) 

But it throws many errors during compilation. How can I do that?

Update
As said in the answers - using the std::unique_ptr::reset method led to undefined behaviour. Now I know, that in such cases I should use a standard pointer.

like image 548
Tomasz Kasperczyk Avatar asked Feb 13 '15 14:02

Tomasz Kasperczyk


People also ask

Is it possible to take the address of a smart pointer?

At most, what you may want to do is initialize the smart pointer with the newly allocated object, for example: Do not ever take the address of a reference. Ever. For no reason. It's morally wrong.

What is a smart pointer in C++?

A C++ smart pointer is a wrapper class. While the objects of this class look like regular pointers, they have additional functionalities – e.g., reference counting, automatic object destruction, and C++ memory management. 1. Memory leaks: how do these happen?

How do I assign a different object to a unique_pointer?

unique_ptr stores one pointer only. We can assign a different object by removing the current object from the pointer. Notice the code below. First, the unique_pointer is pointing to P1. But, then we remove P1 and assign P2 so the pointer now points to P2.

How to assign an address to a pointer in C?

Assigning an address to a pointer Given a variable var of type t and a variable var_ptr of type pointer to t ( t * ), it possible to assign The following example shows the declaration and value assignment of pointers (file pointer_example_1.c ): Lines 4 and 5 define two integers and two pointers to integer respectively.


2 Answers

Try std::unique_ptr::reset

void foo(bar &object){     std::unique_ptr<bar> pointer;     pointer.reset(&object); } 

But be aware this is not recommended, you should not create a unique_ptr to a reference that is being passed to a function. At the end of the function, when pointer is being destroyed it will try to destroy object as well, and it won't be available outside the function call, resulting in an access memory error.

Example: This will compile, but give a runtime error.

struct bar{ int num;};  void foo(bar &object){     std::unique_ptr<bar> pointer;     pointer.reset(&object); }  int main() {     bar obj;     foo(obj);     obj.num; // obj is not a valid reference any more.     return 0; } 

On the other hand you might want to consider using shared_ptr this can help you to decide: unique_ptr or shared_ptr?.

like image 140
Raydel Miranda Avatar answered Sep 20 '22 14:09

Raydel Miranda


You can only assign another unique_ptr or the nullptr. If you think about it, this makes sense, too (though reset will let you do what you want, but I think this is actually a bug or deficiency in unique_ptr).

A unique_ptr is the exclusive owner of the pointed-to object. When it goes out of scope, it will delete the object.
This means that your function has sink semantics. The pointer you pass in (or rather the pointed-to object") is consumed, that is, it "disappears" (sinks) inside the function. You pass in an object by reference (an object which is not even necessarily heap-allocated, prepare for a surprise if you pass in an object with automatic storage!) and suddenly it's gone. Bang.

Sink semantics should be communicated properly. You should pass a unique_ptr as function parameter. Unique pointers cannot be copied, so this will force the user of that function to use std::move, creating awareness of what is acutally happening.

Having an object "disappear" is a nasty surprise, this shouldn't just happen unintentionally.

like image 33
Damon Avatar answered Sep 19 '22 14:09

Damon