Reputation: 147
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
?
auto_ptr
for A[]
or char[]
because auto_ptr calls delete not delete[]
.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
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
Reputation: 72271
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).
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
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
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
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:
auto_ptr
which prevents memory leaks, period)On second thought, you should probably read Herb Sutter on this. He knows more than I do. ;-)
Upvotes: 2