Auto_ptr functions and usage

Source: Internet
Author: User
Tags hosting

Many people know the standard auto_ptr smart pointer mechanism, but seldom use it. This is really a pity, because auto_ptr elegantly solves common problems in C ++ design and coding, and correctly uses it to generate robust code. This article explains how to correctly use auto_ptr to make your code more secure-and how to avoid dangerous but common misuse of auto_ptr, which can cause intermittent onset and difficult to diagnose bugs.

1. Why is it called an "automatic" pointer? Auto_ptr is just one of the many possible smart pointers. Many business libraries provide more complex smart pointers for a wide range of uses, from managing the number of references to providing advanced proxy services. We can regard the Standard C ++ auto_ptr as the ford escort of the smart pointer (Elmar Note: it may be a suitable family model for Ford): A simple and general smart pointer, it does not contain all tips, not as luxurious as dedicated or high-performance smart pointers, but it can do a lot of common work well and is suitable for everyday use.

What auto_ptr does is to dynamically allocate objects and automatically clean up objects when they are no longer needed. Here is a simple code example. It is not safe because auto_ptr is not used:

// Example 1 (a): original code //

Void F () {T * PT (new t );

/*... More code ...*/

Delete pt ;}

Most of us write similar code every day. If the F () function has only three rows and there is no accident, it may be good to do so. However, if F () Never executes the delete statement, or is returned prematurely, or an exception is thrown when the function body is executed, the allocated object is not deleted, thus, we have produced a classic memory leakage.

A simple way to make Example 1 (a) safe is to encapsulate pointers in a "smart" object similar to pointers, this object owns this pointer and can automatically delete the object referred to by this pointer during destructor. Because this smart pointer can be simply treated as an automatic object (that is, it will be destroyed automatically when it is out of scope), it is naturally called a "smart" pointer:

// Example 1 (B): security code, using auto_ptr //

Void F () {auto_ptr <t> Pt (new t );

/*... More code ...*/

} // Cool: When Pt is out of scope, the Destructor is called. // The object is automatically deleted.

At present, the code will not leak T-type objects, no matter whether the function Exits normally or throws an exception, because the PT destructor will always be called at the time of exit of the stack. The cleanup is performed automatically.

Finally, using an auto_ptr is as easy as using a built-in pointer. If you want to "undo" the resource and use manual ownership again, you just need to call release ():

// Example 2: Use an auto_ptr //

Void g () {T * pt1 = new t; // now, we have an allocated object.

// Pass the ownership to an auto_ptr object auto_ptr <t> pt2 (pt1 );

// Use auto_ptr just like we used a simple pointer before * pt2 = 12; // like "* pt1 = 12;" pt2-> somefunc (); // like "pt1-> somefunc ();"

// Use get () to obtain the pointer value assert (pt1 = pt2.get ());

// Use release () to revoke ownership T * pt3 = pt2.release ();

// Delete this object by yourself, because now // No auto_ptr has this object Delete pt3;

} // Pt2 no longer has any pointer, so do not // try to delete it... OK, do not delete it again

Finally, we can use the reset () function of auto_ptr to reset auto_ptr so that it has another object. If this auto_ptr already has an object, it will first Delete the existing object, so calling reset () is like destroying this auto_ptr, and then creating a new object and having a new object:

// Example 3: Use reset ()//

Void H () {auto_ptr <t> Pt (New T (1 ));

PT. Reset (New T (2); // Delete the first t allocated by "new T (1 )".

} // Finally, PT has a scope and // The second t has been deleted.

 

Auto_ptr usage:

1. You need to include the header file <memory>

2. constructor: explicit auto_ptr (x * p = 0) Throw (); hand over pointer P to auto_ptr object hosting

3. copy constructor: auto_ptr (const auto_ptr &) Throw (); Template <class Y> auto_ptr (const auto_ptr <Y> & A) Throw (); pointer custody will be transferred

4. destructor :~ Auto_ptr (); releases the space pointed to by pointer P

5. two member functions are provided: x * Get () const throw (); // The saved pointer is returned, and the pointer x * release () const throw () is retained in the object (); // returns the saved pointer, which is not retained in the object

Auto_ptr implements key points 1. Use features to "automatically analyze the objects on the stack when they leave the scope"

2. for the dynamically allocated memory, the function scope is manually controlled by the programmer, which brings convenience to the programmer but inevitably avoids Memory leakage caused by negligence. After all, only the compiler is the most reliable.

3. auto_ptr builds an object A on the stack. In object A, wrap dynamically allocates the memory pointer P. All operations on the pointer P are converted to operations on Object. In the destructor of A, the space of P is automatically released, and the Destructor is automatically called by the compiler.

Let's look at the most practical example:

# Include <iostream>

# Include <memory>

Using namespace STD;

Class TC

{

Public:

TC () {cout <"Tc ()" <Endl ;}

~ TC () {cout <"~ TC () "<Endl ;}

};

Void Foo (bool isthrow)

{

Auto_ptr <TC> PTC (new TC); // method 2

// TC * PTC = new TC; // method 1

Try

{

If (isthrow)

Throw "Haha ";

}

Catch (const char * E)

{

// Delete PTC; // method 1

Throw;

}

// Delete PTC; // method 1

}

Int main ()

{

Try

{

Foo (true );

}

Catch (...)

{

Cout <"caught" <Endl;

}

System ("pause ");

}

1. If solution 1 is used, you must consider that the function releases the allocated memory when the throw exception occurs. The result is that you must manually delete PTC at each branch;

2. if solution 2 is used, you don't have to worry about when to release the memory. No matter what the Foo () exits, the destructor of the object on the stack will be called, therefore, the memory indicated by the pointer hosted in must be safely released.

So far, the advantages of smart pointers are clear.

But pay attention to a trap in use, that is, the pointer hosting permission will be transferred. For example, in the above example, if auto_ptr <TC> PTC (new TC); auto_ptr <TC> ptc1 = PTC; then ptc1 will own this pointer, while PTC will not, if you use PTC for reference, memory errors will inevitably occur.

To avoid this problem, you can consider using a smart pointer with reference count, such as boost: shared_ptr.

Auto_ptr does not reduce program efficiency, but auto_ptr does not apply to arrays. auto_ptr cannot be used in a large scale at all.
Shared_ptr must also be used with weaked_ptr. Otherwise, it is easy to trigger loop reference and memory will never be reclaimed.
In theory, the rational use of containers and smart pointers can completely avoid memory leaks, with only a negligible reduction in efficiency (a maximum of 1% of medium-sized and above programs)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.