C + + shared_ptr usage considerations.

Source: Internet
Author: User
Tags throw exception

Article 1: Do not put a native pointer to multiple shared_ptr management
int New int ; shared_ptr<int> p1 (PTR); shared_ptr<int//logic Error 
PTR object deleted 2 times This problem is likened to "two dragons harnessing the water", which can also occur in native pointers. clause 2: Do not give the this pointer to shared_ptr
class test{public:    void do () {  m_member_sp =  shared_ptr<test> (  This );  } Private :    shared_ptr<Test> m_member_sp;}; TestNew  test;shared_ptr<Test> local_sp (t);p->do ();
What happened, the T object was deleted 2 times! The T object is administered to local_sp, and then in m_member_sp = Shared_ptr<test> (this), a God is asked to manage T. This has occurred in clause 1 "Two dragons flood" error.

Clause 3: Do not let the shared_ptr circular reference.

//---------------------------------------------classDog;classanimal{ Public:    ~Animal () {cout<<"Animal Deconstructor"<<Endl; } shared_ptr<Dog>_dog;};//---------------------------------------------classdog{ Public:    ~Dog () {cout<<"Dog Deconstructor"<<Endl; } shared_ptr<Animal>_animal;};//---------------------------------------------intMain () {shared_ptr<Dog> Dog = make_shared<dog>(); shared_ptr<Animal> Animal = make_shared<animal>(); Dog->_animal =Animal; Animal->_dog =Dog; cout<<"--------------------------"<<Endl; return 0;}

So Animal and Dog will not be recycled.

Workaround, Place shared_ptr<Dog> _dog or shared_ptr<Animal> _ Animal one of them is replaced by a weak_ptr.

Clause 4: Do not create shared_ptr in function arguments

Function (shared_ptr<int> (new int), g ());  Defective possible process is first new int, then g (), g () exception occurred,shared_ptr<int> not created, int memory leak shared_ptr<int> p (new int ()); F (P, g ()); Boost recommended notation Article 5: Creating shared_ptr within Objects as I said earlier, you cannot throw the this pointer directly to shared_ptr. But there is no ban on generating your own shared_ptr inside an object //This is an example of boost. class Y:public boost::enable_shared_from_this<y>{boost::shared_ptr<y> getself ()    {return Shared_from_this ();    }}; The principle is like this. Shared_ptr<t> p (New T) of the normal (without inheriting Enable_shared_from_this) class T.p takes 8 bytes as a stack object, and P allocates 16 bytes on the heap to record the reference count of the (new T) object to save"Intelligent information" such as reference counting. Share_ptr does not have "embed (intrusive)" to the T object, or the T object is not known to Share_ptr . love. Y objects are different, Y objects have been "embedded" in some share_ptr-related information in order to find "global"that 16 bytes of this object's "smart info".  The theory is over, it's a trap .y y;boost::shared_ptr<y> p= y.getself ();//Ignorance of the code, Y is not new at all y* y = new Y;boost::shared_ptr<y> p= y->getself ();//plausible, still the program crashed. The boost document says that before calling Shared_from_this (), there must be a normal way to create the shared_ptr boost::shared_ptr<y> Spy (new Y)boost::shared_ptr<y> p = spy->getself ();//ok clause 6: Be careful when dealing with objects that are not new. int* pi = (int*) malloc (4) shared_ptr<int> sp (PI); Delete horse mouth not malloc donkey head. Article 7: Impact of multithreading on reference counting.  if it is a lightweight lock, such as interlockincrement, it has little effect on the program .In the case of a heavyweight lock, consider the context switching overhead caused by share_ptr maintaining the reference count. shared_ptr after version 1.33 uses Lock-free (similar to interlockincrement function family) for reference counting operationsoperation, should be efficient, and ensure thread safety (libraries must be secure, programmers do not interfere with these hidden things opportunities). the boost document says that the behavior is read,write at the same time as the shared_ptr operation. This is because the shared_ptr itself has two members of the PX,PI. multithreading at the same time to the PX read and write is a problem. The same is true for a global variable with an int that is multithreaded to read and write.

Article 8: Array of objects with Shared_array int* pint = new int[100];shared_array<int> P (pint); since shared_ptr corresponds to delete, it is obvious that a delete[] counterpart Shared_array  Article 9: Learn to use a delete device struct Test_deleter{   void operator () (test* p) {:: Free (p); }};test* t = (test*) malloc (sizeof (Test));new (t) Test; shared_ptr<test> sp (T, Test_deleter ());//delete can change share_ptr destroy object behavior with the Shared_array, it's useless. Template<class t>struct Array_deleter{   void operator () (t*) {delete[] p; }};int* pint = new int[100];shared_ptr<int> P (Pint, array_deleter<int> ());  Article 10: Learn to use dispensers The place where the reference count is stored is the heap memory, which requires 16-20 bytes of overhead. Large amounts of shared_ptr can cause large amounts of memory fragmentation. The 3rd parameter of the Shared_ptr constructor is the allocator, which resolves the problem.  shared_ptr<test> P ((new Test), Test_deleter (), mallocator<test> ());Note that the Test_deleter is for the test class. The allocator is for shared_ptr internal data.  mallocator<test> () is a temporary object (stateless), conforming to the STL allocator specification.  template <typename t>class Mallocator {//slightly ... T * ALLOCATE (const size_t N) Const {return singleton_pool<t,sizeof (T) >::malloc ();    }//slightly ...  mallocator incoming test, the actual type of assignment is actuallyclass boost::d etail::sp_counted_impl_pda<class Test *,struct Test_deleter,class Mallocator<class test> >This is printed with typeID (T). Name (). may be associated with rebind. the terms of weak_ptr need to be checked for legality before use. weak_ptr<k> WP;  {shared_ptr<k> sp (new K); Sp.use_count () ==1wp = SP; WP does not change the reference count, so Sp.use_count () ==1shared_ptr<k> SP_OK = Wp.lock (); WP is not overloaded with operators. You can only take the object pointed to}shared_ptr<k> sp_null = Wp.lock (); Sp_null. Use_count () ==0; because the SP and SP_OK are out of scope in the code above, the K objects they hold are already freed. A Sp_null object that holds a null pointer is obtained. You need to call the wp.expired () function before using WP to judge. Because WP still exists, although the reference count equals 0, there is still a "global" storage block holding this count information. Until the last Weak_ptr object is refactored, this "heap" of storage blocks can be recycled. Otherwise weak_ptr cannot wait until the current state of the pointer resource it holds. clause 12 do not new shared_ptr<t>Originally shared_ptr is to manage pointer resources, do not introduce a need to manage the pointer resources shared_ptr<t>* clause 13 try not to get class b{...};class D:public b{...}; Inheritance Hierarchy Relationship shared_ptr<b> sp (new D); A pointer to D is stored by an implicit conversion. b* B = Sp.get (); Shared_ptr's hard-to-hide native pointers were so planed out. d* D = dynamic_cast<d*> (b); Is this a valid reason to use Get?  the right approachshared_ptr<b> SPB (new D);shared_ptr<d> spd = shared_dynamic_cast<d> (SPB);//Pointer to sub-classshared_ptr is acting like a native pointer, the native pointer is capable of doing, and it is basically capable.  another error related to getshared_ptr<t> sp (new T);shared_ptr<t> SP2 (Sp.get ());//Another "Two dragons flood" example, the pointer will be deleted 2 times and error.   clause 14 do not memcpy shared_ptr shared_ptr<b> SP1 (new B);shared_ptr<b> SP2;memcpy (&sp2,&sp1,sizeof (shared_ptr<b>));//sp2.use_count () ==1Obviously, the reference count does not grow correctly, not through the normal path (copy construct, assignment operation).   clause 15 use boost predefined macros to change the shared_ptr behavior.  shared_ptr behavior is controlled by macros like Boost_sp_disable_threads. Need to learn what they really are. Master Andrei Alexandrescu designed a smart pointer based on template policy design pattern, which is customized by several template parameters .the behavior of the smart pointer. Boost does not agree, the official explanation is: the need for a unified interface, so as to facilitate large-scale writing. smart_ptr<t,ownershippolicy,conversionpolicy,checkingpolicy,storagepolicy> sp (new T);The disadvantages of these interfaces are complex in appearance and look like a big erhualian. The advantage is that the customer programmer can easily customize the behavior.   Clause 17 constructor call Shared_from_this Throw exception class Holder:public enable_shared_from_thisPublic :Holder () {shared_ptrint x = Sp.use_count ();    }};The same as the previous Noodles 5, does not conform to the Enable_shared_from_this use premise.

Summary: Study a day summed up more than 10 articles, long-term research I am afraid to appear in clause 100. Why do you use shared_ptr? There are many open source libraries with shared_ptr, and shared_ptr has "contagious" (a Netizen language: like drugs on the can not be thrown off), put aside it will have more serious multi-dragon flood-water phenomenon. As a substitute for native pointers, shared_ptr can solve a certain memory leak problem. In fact, when beginners native pointer, everyone has encountered a wild pointer, delete two times, forget to delete and so on. Learning shared_ptr will also come across. SHARED_PTR does improve the above problems and does not solve the problem completely. Shared_ptr may dominate in the future, it is most likely to command the lake, otherwise a large pile of auto_ptr,weak_ptr, the original hands, scoped_ptr coexistence of people confused.

Content reprinted from: http://blog.sina.com.cn/s/blog_62b4e3ff0100v1tc.html

C + + shared_ptr usage considerations.

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.