In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)06/01 Report--
Text
Back to the top.
1. Do not manually release heap resources returned from the function
Suppose you are working on a library that simulates Investment, and different Investmetn types inherit from the Investment base class
1 class Investment {...}; / / root class of hierarchy of2 3 / / investment types
Further assume that the library provides us with specific Investment objects through a factory function (Item 7):
1 Investment* createInvestment (); / / return ptr to dynamically allocated2 3 / / object in the Investment hierarchy;4 5 / / the caller must delete it6 7 / / (parameters omitted for simplicity)
As the comment states, it is the responsibility of the caller to release the object returned by createInvesment when it is no longer used. We use the function f to perform this duty:
1 void f () 2 3 {4 5 Investment * pInv = createInvestment (); / / call factory function 6 7... / / use pInv 8 9 delete pInv; / / release object10 11}
This approach looks good, but in some cases it is possible to fail to release objects from createInvestment. In the "…" of the function There may be premature reture statements in the section, and if the return is executed, the last delete statement will never be executed; if createInvesment and delete are in a loop, the break and goto statements will cause the loop to exit prematurely, and the delete will not be executed. It is possible for some statements in the to throw an exception, in which case the control flow will again fail to execute to the delete. No matter how delete is skipped, it will reveal not only the memory used by the Invesment object, but also any resources owned by the Investment object.
Of course, careful programming can prevent such errors, but you should think that the code may change over time. During the maintenance of the software, some people may add a return or continue statement to it without fully understanding the resource management strategy of this function. To make matters worse, the "…" of the f function It is partially possible to call a function that never throws an exception, but after the function is "improved", it throws an exception. So relying on f to reach the delete statement is usually not feasible.
Back to the top.
two。 Manage resources that need to be released manually through objects
To ensure that the resources returned from the createInvestment are always released, we need to put the resources into an object, and when you leave the function f, the object's destructor automatically releases the resources owned by the object. In fact, we have already said half of this clause: by putting resources into objects, we can rely on C++ 's destructor automatic invocation mechanism to ensure that resources are released. (the other half will talk about it in a minute)
2.1 use auto_ptr to manage resources
Many resources are dynamically allocated to the heap, they are used in a separate block or function, and these resources should be released when the control flow leaves the block or function. The auto_ptr in the standard library is tailored to this situation. Auto_ptr is an object like a pointer (smart pointer), and its destructor automatically calls the delete function for the object it points to. The following demonstrates how to use auto_ptr to prevent possible resource leaks:
1 void f () 2 3 {4 5 std::auto_ptr pInv (createInvestment ()); / / call factory 6 7 / / function 8 9. / / use pInv as10 11 / / before12 13} / / automatically14 15 / / delete pInv via16 17 / / auto_ptr's dtor
2.2 two key points of using objects to manage resources
This simple example points to two key points of using objects to manage resources:
Resources should be transferred to the resource management object as soon as they are obtained. As you can see from the example above, the resource returned by createInvestment is used to initialize the auto_ptr pointer that manages it. In fact, the idea of managing resources with objects is often called "resource acquisition is initialization time" (Resource Acquisition Is Initialization RAII), because it is very common to put resource acquisition and resource management object initialization in the same statement. Sometimes the acquired resource is used to assign a value to the resource management object rather than initialization, but either way, control is transferred to the resource management object as soon as the resource is acquired.
Resource management objects use their destructors to ensure that resources are released. Because no matter how the control flow leaves the block or function, the destructor is automatically called when the object is destroyed (for example, when an object is out of scope), so the resource can be released correctly. Throwing an exception when releasing resources can make the problem tricky, which is discussed in Item8, and we are no longer worried about it.
Because auto_ptr automatically delete the resource it points to when it is destroyed, it is important to have multiple auto_ptr pointing to a single object. If there is more than one, the object will be delete multiple times, which can lead to undefined behavior. To prevent such problems, auto_ptrs has a distinctive property: the copied pointer (through the copy constructor or the copy assignment operator) will be set to null, and the copied pointer will have ownership of the resource.
1 std::auto_ptr / / pInv1 points to the 2 3 pInv1 (createInvestment ()); / / object returned from 4 5 / / createInvestment 6 7 std::auto_ptr pInv2 (pInv1); / / pInv2 now points to the 8 9 / / object; pInv1 is now null10 11 pInv1 = pInv2; / / now pInv1 points to the12 13 / / object, and pInv2 is null
2.3Using shared_ptr to manage resources
The peculiar copying behavior, coupled with "there can be no more than one auto_ptr pointing to resources managed by auto_ptr", makes auto_ptrs not the best way to manage all dynamically allocated resources. For example, STL containers require "normal" copy behavior, so you cannot put containers into auto_ptr.
An alternative to Auto_ptr is to use the "smart pointer for reference counting" (reference-counting smart pointer RCSP). RCSP is a pointer that tracks how many objects point to the same particular resource, and the resource can only be released without a pointer. Therefore, the behavior provided by RCSP is similar to the garbage collection mechanism. Unlike the garbage collection mechanism, RCSP does not prevent circular references (for example, two objects that are not used point to each other and appear to be being used. )
TR1's tr1::shared_ptr (see Item54) is a RCSP, so you can implement f like this:
1 void f () 2 3 {4 5... 6 7 std::tr1::shared_ptr 8 9 pInv (createInvestment ()); / / call factory function10 11. / / use pInv as before12 13} / / automatically delete14 15 / / pInv via shared_ptr's dtor
This code looks roughly the same as using auto_ptr, but copying shared_ptrs is more natural:
1 void f () 2 3 {4 5... 6 7 std::tr1::shared_ptr / / pInv1 points to the 8 9 pInv1 (createInvestment ()); / / object returned from10 11 / / createInvestment12 13 std::tr1::shared_ptr / / both pInv1 and pInv2 now14 pInv2 (pInv1); / / point to the object15 pInv1 = pInv2; / / ditto-nothing has16 / / changed17. 18} / pInv1 and pInv2 are19 / / destroyed, and the20 / / object they point to is21 / / automatically deleted
Because copying tr1::shared_ptrs works the way you want, they can be used in contexts such as STL containers and other contexts, where the quirky way of copying auto_ptr is no longer appropriate.
2.4 do not use auto_ptr and shared_ptr for dynamically allocating arrays
Don't be misled. This clause is not intended to introduce auto_ptr,tr1::shared_ptr or other types of smart pointers. This clause talks about the importance of using objects to manage resources. Using Auto_ptr and tr1::shared_ptr is just an example. (for more information on tr1::shared_ptr, see Item14 18 and 54)
The destructors for Auto_ptr and tr1::shared_ptr use delete instead of delete []. (Item16 describes the difference) this means that it is not a good idea to store dynamically allocated arrays in auto_ptr or tr1::shared_ptr, which unfortunately can be used by compiling:
1 std::auto_ptr / / bad idea! The wrong2 3 aps (new std::string [10]); / / delete form will be used4 5 std::tr1::shared_ptr spi (new int [1024]); / / same problem
You'll be surprised to find that there's nothing like auto_ptr or tr1::shared_ptr for dynamically allocating arrays in C++, nor in TR1. Because vector and string can basically replace dynamic allocation of arrays. If you still think it's good to have classes like auto_ptr and tr1::shared_ptr for dynamically allocating arrays, take a look at Boost (Item 55). You will be very pleased to find that the boost::scoped_array and boost::shared_array classes provide what you are looking for.
Back to the top.
3. Other questions
In this clause, the guidelines for using objects to manage resources mean that if you manually release resources yourself (for example, using delete instead of a resource management class), you are doing something wrong. Preloaded resource management classes like auto_ptr and tr1::shared_ptr make it easier to comply with this clause, but sometimes when you use a resource, you will find that these prefabricated classes do not do what you want. In this case, you need to write your own resource management class. It's not very difficult, but there are some subtleties to consider. These considerations will be discussed in Item14 and Item15.
Finally, I must point out that the native pointer return type of createInvestment is resource leak, because it is easy for callers to forget to call delete (even if they use auto_ptr and tr1::shared_ptr to execute delete, they still need to remember to put the return value of createInvestment in the smart pointer object). To deal with this problem, you need to call a revised version of createInvestment, which will be discussed in Item18.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 242
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.