Hariom Singh
Hariom Singh

Reputation: 3642

unique pointer vs raw pointer

Trying to understand the unique_pointer vs raw pointer access

#include <iostream>
#include <memory>

int main() {
    int a = 10;
    int *x = &a;
    int *y = &a;
    std::unique_ptr<int> p1 = std::make_unique<int>(a);
    std::cout<<*x<<*p1<<*y<<"\n";
    // prints 101010
    *p1 = 20;
    std::cout<<*x<<*p1<<*y<<"\n";
    // prints 102010
    *x =30;
    std::cout<<*x<<*p1<<*y<<"\n";
    // 302030
    return 0;
}

Output

101010
102010
302030

Program ended with exit code: 0

In the above code x, y,p1 are all pointing to variable a; so change of value a should have reflected to all the pointers dereferencing .

Please do help me to understand the behaviour I am few of the guys who all are now moving from use of raw pointers to smart pointers.

Upvotes: 2

Views: 1968

Answers (2)

Ross Bae
Ross Bae

Reputation: 41

The code below is based on MSVC.

Reason

  • std::make_unique() let you make new object, not reference the parameter
    • You can find that the unique_ptr p1 gets a different address

      int a = 10;                                         // &a = 0x000000bd7d5dfb74
      int* x = &a;                                        // x = 0x000000bd7d5dfb74
      int* y = &a;                                        // y = 0x000000bd7d5dfb74
      
      std::unique_ptr<int> p1 = std::make_unique<int>(a); // p1._Mypair._Myval2 = 0x00000288fbbd6ba0
      std::cout << *x << *y << *p1 << "\n";
      
      *p1 = 20;
      std::cout << *x << *y << *p1 << "\n";
      
      *x = 30;
      std::cout << *x << *y << *p1 << "\n";
      

screenshot

Solution

  • As Some programmer dude said, use std::unique_ptr<int> p1(&a);

    • This results that the unique_ptr indicates the same address

      int* a = new int(10);        // a = 0x0000027411117260
      int* x = a;                  // x = 0x0000027411117260
      int* y = a;                  // y = 0x0000027411117260
      
      std::unique_ptr<int> p1(a);  // p1._Mypair._Myval2 = 0x0000027411117260
      std::cout << *x << *y << *p1 << "\n";
      
      *p1 = 20;
      std::cout << *x << *y << *p1 << "\n";
      
      *x = 30;
      std::cout << *x << *y << *p1 << "\n";
      
  • FYI, as the unique_ptr p1 will free the memory of a, you do not need to free the memory explicitly.

screenshot

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409442

You're wrong, p1 doesn't point to a.

Instead std::make_unique<int>(a) create a brand new int object and initialize it to the current value of a.


To make p1 point to a you need to do

std::unique_ptr<int> p1(&a);

However that brings with it other problems, like p1 taking over the ownership of &a, and attempting to free that memory when p1 is destructed (which is not possible).

You could use the Boost null_deleter to avoid the last problem.

But I recommend that in most situation you should not look at the smart pointers a simple self-deleting pointers, but instead from an ownership perspective.

Upvotes: 6

Related Questions