5 Answers
5

The direct replacement for auto_ptr (or the closest thing to one anyway) is unique_ptr. As far as the "problem" goes, it's pretty simple: auto_ptr transfers ownership when it's assigned. unique_ptr also transfers ownership, but thanks to codification of move semantics and the magic of rvalue references, it can do so considerably more naturally. It also "fits" with the rest of the standard library considerably better (though, in fairness, some of that is thanks to the rest of the library changing to accommodate move semantics instead of always requiring copying).

The change in name is also (IMO) a welcome one -- auto_ptr doesn't really tell you much about what it attempts to automate, whereas unique_ptr is a fairly reasonable (if terse) description of what's provided.

Just a note on the auto_ptr name: auto suggests automatic as in automatic variable, and it refers to one thing that auto_ptr do: destroy the managed resource in its destructor (when it goes out of scope).
– Vincenzo PiiFeb 5 '12 at 19:09

@HowardHinnant interesting doc! it is strange in a sense that if std::sort() is has a specialization for std::unique_ptr to use the move semantic as needed. I wonder why std::sort() can't be specialized for std::auto_ptr to correct the copy issue mentioned in the doc. Thanks in advance.
– HeiNov 15 '17 at 7:10

2

@Hei: std::sort doesn't have a specialization for unique_ptr. Instead it was re-specified to never copy. So auto_ptr actually does work with the modern sort. But the C++98/03 sort is just an example algorithm here: Any generic algorithm (std-supplied or user-written) that assumes that copy syntax has copy semantics will likely have a run-time error if used with auto_ptr, because auto_ptr silently moves with copy syntax. The issue is much larger than just sort.
– Howard HinnantNov 15 '17 at 14:10

I found the existing answers great, but from the PoV of the pointers. IMO, an ideal answer should have the user/programmer's perspective answer.

First thing first (as pointed by Jerry Coffin in his answer)

auto_ptr could be replaced by shared_ptr or unique_ptr depending upon situation

shared_ptr : If you are concerned about freeing of resource/memory AND if you have more than one function that could be using the object AT-DIFFERENT times, then go with shared_ptr.

By DIFFERENT-Times, think of a situation where the object-ptr is stored in multiple data-structure and later accessed. Multiple threads, of course is another example.

unique_ptr : If all you are concerned is freeing memory, and the access to object is SEQUENTIAL, then go for unique_ptr.

By SEQUENTIAL, I mean, at any point object will be accessed from one context. E.g. a object that was created, and used immediately after creation by the creator. After creation the object is stored in FIRST data-structure. Then either the object is destroyed after the ONE data-structure or is moved to SECOND data-structure.

From this line, I will refer shared/unique _ptr as smart-pointers. (auto_ptr is also smart-pointer BUT because of flaws in it's design,for which they are being deprecated, and which I think I will point out in next lines, they should not be grouped with smart-pointer. )

Single most important reason as to why auto_ptr was deprecated in favor of smart-pointer is
assignment-semantics If it wasn't for that reason, they would have added all the new goodies of move semantics to the auto_ptr instead of deprecating it. Since the assignment-semantics was most-disliked feature, they wanted that feature to go away, but since there is code written that uses that semantics, (which standards-committee can not change), they had to let go of auto_ptr, instead of modifying it.

Now coming to the reason WHY the copy assignment itself was so disliked, I have this theory :

Not all programmers read books or standards

auto_ptr on the face of it, promises you ownership of the object

the little-* (pun intended), clause of the auto_ptr, which is not read by all the programmers, allows, assignment of one auto_ptr to another, and transfers the ownership.

Research has shown this behavior is intended for 3.1415926535 % of all usage, and unintended in other cases.

The unintended behavior is really disliked and hence the dislike for the auto_ptr.

(For the 3.1415926536% of programmers who intentionally wants to transfer the ownership C++11 gave them std::move(), which made their intention crystal clear for all the interns who are going to read and maintain the code.)

Since you never want two auto_ptr values pointing to the same object (since they don't give shared ownership, the first one to die will leave the other with a lethal heritage; this is also true for unique_ptr usage) , can you suggest what was intended in those remaining 96.8584073465% of all usage?
– Marc van LeeuwenJun 19 '14 at 4:49

Can't speak for the all of them, but I would guess, they would think the object ownership is being moved and NOT just duplicated, which is erroneous.
– Ajeet GangaSep 22 '14 at 19:47

@AjeetGanga In the following phrase 'the little-* (pun intended),' you mentioned as "pun intended". This phrase is new for me and anyhow I googled it and got to know that there is some joke that was purposefully done here. What is that joke here? Just curious to know that.
– VINOTH ENERGETICMay 5 '17 at 4:43

@AjeetGanga You mentioned like 'the little-* (pun intended), clause of the auto_ptr, which is not read by all the programmers, allows, assignment of one auto_ptr to another, and transfers the ownership'. Let say I have two auto ptr's as a and b to integer. I am doing the assignment as *a=*b; Here only value of b is copied to a. I Hope Ownership of both a and b is still with the same people. You mentioned like owenership will be transferred. How it will be?
– VINOTH ENERGETICMay 5 '17 at 4:49

Functionally, C++11's std::unique_ptr is the "fixed" std::auto_ptr: both of them are suitable when - at any point in time during execution - there should be a single smart-pointer owner for a pointed-to object.

The crucial difference is in copy-construction or assignment from another un-expiring smart pointer, shown on the => lines below:

Above, ap3 quietly "steals" ownership of *ap, leaving ap set to a nullptr, and the problem is that can happen too easily, without the programmer having thought through its safety.

For example, if a class/struct has a std::auto_ptr member, then making a copy of an instance will release the pointer from the instance being copied: that's weird and dangerously confusing semantics as usually copying something doesn't modify it. It's easy for the class/struct author to overlook the release of the pointer when reasoning about invariants and state, and consequently accidentally attempt to dereference smart-pointer while null, or just not still have expected access/ownership of the pointed-to data.

auto_ptr cannot be used in STL containers because it has a copy constructor that does not meet requirements of container CopyConstructible. unique_ptr does not implement a copy constructor, so containers use alternate methods. unique_ptr can be used in containers and is faster for std algorithms than shared_ptr.