August
August

Reputation: 1819

C++ making and destroying unique_ptr pointer

I am learning ways to use pointer with std::unique_ptr. My code:

#include <iostream>
#include <memory>

class object{
public:
    void say(){
            std::cout<<"hi";
    }
};

int main(){
      std::unique_ptr<object> p = 
                  std::unique_ptr<object>(new object);
      p->say();
}

My questions are:

  1. Am I using std::unique_ptr correctly?

  2. How can I delete or remove this (p) pointer, so there is no memory usage or leak?

Upvotes: 1

Views: 5412

Answers (5)

Humam Helfawi
Humam Helfawi

Reputation: 20264

Yes, you are using it the right way. However, if C++ 14 is available you may create it like this:

auto p = std::make_unique<object>();

About deleting it. It does not need to be deleted. This is the idea of smart pointers in general. It will delete the memory that it was allocated by itself when it goes out of scope.

Upvotes: 2

Davide Spataro
Davide Spataro

Reputation: 7482

  1. Yes, you are not using the unique_ptr in a bad way. unique_ptr uses the Resource Acquisition Is Initialization paradigm - i.e. managing the new Object is a unique_ptr's responsibility.

  2. This means that you don't have to explicitly delete the pointer p, because when the unique_ptr goes out of scope (end of the block, or function in this case) its destructor will manage to free the memory in the correct way without causing any leak.

Look at the following code (that works similarly to unique_ptr):

template<class T>
class ScopedPointer : NonCopiable{
private:
    T * pointer;
public:
     ScopedPointer( T  *p): pointer(p){};

    virtual ~ScopedPointer(){

            delete pointer;
    };
    T * operator->() const {return pointer;};
    T & operator*() const {return *pointer;};

};

The ScopedPointer destructor will take care of deleting the raw pointer!

Upvotes: 1

TartanLlama
TartanLlama

Reputation: 65600

std::unique_ptr<object> p = std::unique_ptr<object>(new object);

This is fine, but you could simplify this like so:

std::unique_ptr<object> p { new object{} };

Or like this in C++14:

auto p = std::make_unique<object>();

You don't need to delete a std::unique_ptr, that's the whole point. When p goes out of scope (at the end of main), the pointee will be deleted automatically.

That said, there's no need to use dynamic allocation in this example. You should just use an automatic variable instead:

int main(){
      object p{};
      p.say();
}

A good rule of thumb is to use automatic storage duration when you can and dynamic storage duration when you must.


std::make_unique has the advantage of protecting against leaks in situations like this:

process(std::unique_ptr<object>(new object), iMightThrow());

If new object is executed first, then iMightThrow runs and throws, memory will be leaked. std::make_unique guards against this:

process(std::make_unique<object>(), iMightThrow());

Now if iMightThrow() throws, the std::unique_ptr will either not have been created, or it will be destroyed and reclaim the memory.

Upvotes: 8

Marco Giordano
Marco Giordano

Reputation: 610

if you can use C++ 14 you can have a short hand:

auto p = std::make_unique<object>();

There is no memory leak here, the unique_ptr wraps the heap allocation and when it goes out of scope it releases the resource. You don't need to release it manually, just use it as a normal variable, just be careful of it s scope of course.

Upvotes: 0

Viktor Simk&#243;
Viktor Simk&#243;

Reputation: 2627

std::unique_ptr<object> p(new object); is enough.
You don't have to do anything with it, after it goes out of scope it destroys the object.

Upvotes: 2

Related Questions