Likon
Likon

Reputation: 147

Sense of using std::auto_ptr

What is the sense of auto_ptr? Look at this code:

#include <iostream>
#include <memory>

class A
{
public:
    ~A()
    {
        std::cout << "DEST";
    };
};

void func(A* pa)
{
    std::cout << "A pointer";
}

void test()
{
    A a;
    std::auto_ptr<A> pA(new A);
    //func(pA);  //compiler error here cannot convert parameter 1 from 'std::auto_ptr<_Ty>' to 'A *' 
    std::cout << "end";
}

int main(int argc, char* argv[])
{
    test();
    return 0;
}

What's the sense of using this auto_ptr?

The only think is that I dont have to write delete, but whats the sense of pointer if it will be destroyed when I get out of scope. I use pointer to control the live of the variable.

The normal variable initialize is on the stack and pointer on heap, but tell me what is the sense of using the auto_ptr rather then normal pointer?

Upvotes: 3

Views: 5370

Answers (5)

Ed Swangren
Ed Swangren

Reputation: 124702

The only think is that I dont have to write delete

Yup, which is a pretty big benefit considering memory leaks are one of the most common bugs you will run across.

whats the sense of pointer if it will be destoyed when I get out of scope. I use pointer to control the live of the variable.

You shift from that mentality and use scope to define the life of a variable. You simply declare these things in the proper scope and don't have to worry about cleanup anymore. That's the whole point.

Your examples are contrived, but you can still see why it is valuable. Sure, you probably wouldn't forget to call delete in a two line function that does nothing at all. In a real application things get more complicated.

When you new a bunch of objects you can rely on the fact that, when the function exits, the objects will be cleaned up. The same goes for classes; when an instance goes out of scope, you can rely on its destructor to take care of deallocating memory for you. Consider what happens when an exception is thrown. Without the auto_ptr you need to make damn sure that you handle every possible exception and every possible return path to make sure you clean up after yourself.

Also...

The normal variable initialize is on the stack and pointer on heap

Not quite. The pointer in this case has automatic storage duration, what it points to however does not.

The reason your compiler barks at you passing in an auto_ptr is because the function does not take an auto_ptr. You need to call get() to pass in the pointer itself.

That said, you shouldn't be using auto_ptr either; use unique_ptr if you have access to a C++ 0x compiler, which you should.

Upvotes: 6

Kos
Kos

Reputation: 72271

Important

Please remember that std::auto_ptr has many drawbacks and you generally should use std::unique_ptr instead, if your compiler provides it. (If it doesn't, update your compiler! :))

Now back to your question...


Whats the sense of using this auto_ptr? It call the class destructor when getting out of scope as normal class initialize variable (a)

Exactly. The reason for auto_ptr is to enforce strict ownership semantics- so that the object is properly destroyed when the pointer itself is destroyed.

I can't pass this pointer to a function with class pointer (func)

You can, you need to use get() to look up the raw pointer. Using get() when passing the pointer onto a function call means that the function is not going to take ownership of the object (the auto_ptr still owns it and expects it to be still valid after the function returns).

Alternatively, you can use release() on the pointer to obtain the raw pointer AND indicate that the auto_ptr is no longer responsible for the ownership of the object.

I cant use pointer auto_ptr for A[] or char[] because auto_ptr calls delete not delete[]

Yup, that's an issue. That's one of the reasons why no longer use auto_ptr since unique_ptr was introduced. It does the same thing, but is safer (= easier) to use and more versatile.

The only think is that I dont have to write delete, but whats the sense of pointer if it will be destoyed when I get out of scope.

So that you won't forget it :-) Or you can use the auto_ptr (or better unique_ptr as a member in a class object).

but tell me what is the sense of using the auto_ptr rather then normal pointer?

Long story short: Many pointers can point to a single objects. All kinds of smart pointers exist to use the type system for bookkeeping which pointer owns the object (= is responsible for releasing it).


A side note

If you have a class which (may) own an instance of another object, you simply write:

class X {
    // ...
    X() : ptr(new Type()) {}
    X(Type ptr) : ptr(ptr) {}
    // ...
    void setPtr(Type ptr2) { ptr.reset(ptr); }
    // ...
    std::unique_ptr<Type> ptr;
};

If ptr is set, then for example unique_ptr's destructor will take care of deleting the object (if there is one). In the setPtr method, the reset() function will delete the old instance (if there is one) and set the member to the new instance provided (or null - that's OK).

Now compare another situation:

class X {
   // ...
   X() : ptr(new Type()) {}
   X(Type ptr) : ptr(ptr) {}
   // ...
   void setPtr(Type ptr2) {delete ptr; ptr = ptr2;}
   // ...
   Type* ptr;
};

Same behaviour? No! Because now, to have safe C++ code, you additionally need to write a destructor to delete ptr when X is destroyed.

OK now? NO! Because since you have a common destructor, you need to roll up (or block) your own copy constructor and assignment operator, because otherwise you might end up with two instances of X pointing to the same Type object- and both instances would here think that they own this instance and both would sometime try to delete it. Boom, access violation.

Unique_ptr won't allow you to implicitly copy the X object along with the strong reference to ptr, because an unique_ptr is non-copiable (it believes that it is the only unique_ptr to the object, so it's the only smart pointer instance responsible for deleting it - but it's OK if raw, non-owning pointers point to it, as long as they don't try to delete something they don't own!).

And this is not all- unique_ptr can't be copied, but it has a move constructor and a move assignment operator ready for you! Hence you can safely return it from functions, et cetera.

This is how type safety of smart pointers translate to writing safer code.

A golden rule: try to avoid writing "delete" (unless you're writing your own containers or smart pointers). :)

Upvotes: 3

Nicol Bolas
Nicol Bolas

Reputation: 473577

There are a lot of reasons to use auto_ptr (or other smart pointers) to manage memory. Let's change that code:

void test()
{
    A a;
    std::auto_ptr<A> pA(new A);
    if(SomeFunc())
      return;
    //func(pA);  //compiler error here cannot convert parameter 1 from 'std::auto_ptr<_Ty>' to 'A *' 
    std::cout << "end";
}

If pA was not a smart pointer, we would now have a memory leak. But because it is, we know that the memory will properly be freed. There's nothing to worry about. If SomeFunc threw an exception, it would still be freed.

To solve your problem about passing the pointer around, do this:

void test()
{
    A a;
    std::auto_ptr<A> pA(new A);
    func(pA.get());
    std::cout << "end";
}

The pA object still owns the memory; func must not delete it and must not store it.

Upvotes: 4

BЈовић
BЈовић

Reputation: 64223

This is the correct way to do it:

void test()
{
    A a;
    std::auto_ptr<A> pA(new A);
    func(pA.get());
    std::cout << "end";
}

in a case the function func throws an exception, auto_ptr will automatically release memory when it goes out of scope.

Upvotes: 1

Jon
Jon

Reputation: 437434

If you have the luxury of being able to create all your objects on the stack, there's no need for auto_ptr. But think about:

  • returning an object from a function (you can't return a local)
  • making sure that objects returned from functions will either be received by the caller or destroyed in the presence of exceptions
  • aggregating a pointer to an object inside a class (you need to make sure the destructor deletes it, or you can simply make it an auto_ptr which prevents memory leaks, period)
  • ...and much more

On second thought, you should probably read Herb Sutter on this. He knows more than I do. ;-)

Upvotes: 2

Related Questions