Valid C ++ clause 49, valid clause 49

Source: Internet
Author: User

Valid C ++ clause 49, valid clause 49
Understand new-handler Behaviors

The technology described in the terms of this section is that before operator new throws an exception, an error handler specified by the customer is called: new-handler. How to customize and use this memory exception handler when memory allocation fails. The key statement isset_new_handler. The author emphasizes how to allocate class memory to implement different memory allocation error handling functions.
Let's first give an example in the book to figure out how to use the new-handler technology.
The following code:

Void outOfMem () {std: cerr <"Unable to satisfy request for memoryn"; std: abort (); // force terminate the process} int main () {std: set_new_handler (outOfMem); int * pBigDataArray = new int [random distinct L]; return 0 ;}

The above code is called becauseset_new_handler(outOfMem);If the memory allocation fails, it will go to the outOfMen function for further execution. In this way, we will come up with the idea of using different functions to solve the memory allocation problem of different classes defined by ourselves. For example, Class A has A user-defined memory processing function for Class A and Class B has A user-defined memory processing function for Class B. to implement this function, the author proposes the following implementation methods.

However, the memory processing functions we define must have the following features:
1. Make more memory available. In this way, the next memory allocation operation in operator new may be successful. One way is that the program allocates a large block of memory at the beginning and releases it when new-handler is called for the first time.
2. install another new-handler. When the current new-handler cannot obtain more memory, it may be available to the new-handler.
3. Remove new-handler. Pass the null pointer to set_new_handler. Once no new-handler is installed, operator new throws an exception when the memory allocation is unsuccessful.
4. Throw an exception of bad_alloc (or derived from bad_alloc. Such exceptions will not be caught by operator new, so they will not be propagated to the memory claim.
5. No response is returned. Usually abort or exit.

Class NewHandlerHolder {public: explicit NewHandlerHolder (std: new_handler nh): handlere (nh ){}~ NewHandlerHolder () {std: set_new_handler (handler);} private: std: new_handler handler; NewHandlerHolder & (const NewHandlerHolder &); // prevent copying NewHandlerHolder & operator-(const NewHandlerHolder &);}; class Widget {public: static std: new_handler set_new_handler (std: new_handler p) throw (); static void * operator new (std: size_t size) throw (std: bad_alloc); private: static std: new_handler currentHandler;}; std: new_handler Widget :: currentHandler = 0; std: new_handler Widget: handler (std: new_handler p) throw () {std: new_handler oldHandler = currentHandler; currentHandler = p; reutrn oldHandler ;} void * Widget: operator new (std: size_t size) throw (std: bad_alloc) {NewHandlerHolder h (std: set_new_handler (currentHandler )); // install the new-handler return: operator new (size);} void outOfMem (); Widget: set_new_handler (outOfMem ); // set outOfmem to the new-handling function Widget * pw1 = new Widget of the Widget; // if the memory allocation fails, call outOfMEM std: string * ps = new std: string; // if the memory allocation fails, call global new-handling (if any) Widget: set_new_handler (0); // set the Widget's exclusive new-handling to null Widget * pw2 = new Widget; // if the memory allocation fails, an exception is thrown immediately.

Let me explain, the above program, for definitionclass NewHandlerHolderTo save the memory processing function before replacement, let's track the execution process of the above Code. First, declareoutOfMem()And then passWidget::set_new_handler(outOfMem)Statement settingsWidgetInternalstatic std::new_handler currentHandlerVariable. Then, callnew Widget, We enterWidget::operator new(std::size_t size) throw(std::bad_alloc)Function body,NewHandlerHolder h(std::set_new_handler(currentHandler));Statement:NewHandlerHolderWhen the object is replaced, the former memory handler is saved instd::new_handler handlerIn the variable, 2. Set a new new_handler function for the class Widget. Run::operator new(size)Memory Allocation. If an error occurs in memory allocation, the new memory handler is called. When exiting the function body, becauseNewHandlerHolderTo restore the memory processing function, without affecting the execution of other memory allocation exceptions in the future.

The above versions provide the required functions.

However, the author proposes another method to implement the template:

Class NewHandlerHolder {public: explicit NewHandlerHolder (std: new_handler nh): handlere (nh ){}~ NewHandlerHolder () {std: set_new_handler (handler);} private: std: new_handler handler; NewHandlerHolder & (const NewHandlerHolder &); // prevent copying NewHandlerHolder & operator-(const NewHandlerHolder &) ;}; template <typename T> class NewHandlerSupport {public: static std: new_handler set_new_handler (std: new_handler p) throw (); static void * operator new (std: size_t size) throw (std: bad_alloc );...... Private: static std: new_handler currentHandler;}; template <typename T> std: new_handler NewHandlerSupport <T >:: set_new_handler (std: new_handler p) throw () {std:: new_handler oldHandler = currentHandler; currentHandler = p; return oldHandler;} template <typename T> void * NewHandlerSupport <T >:: operator new (std: size_t size) throw (std:: bad_alloc) {NewHandlerHolder h (std: set_new_handler (currentHandler); return: operator new (size); template <typename T> std: new_handler NewHandlerSupport <T> :: currentHandler = 0; class Widget: public NewHandlerSupport <Widget> {};

This implementation method is awkward for me, but it reflects the potential programming value of the template. When we call the statementclass Widget:public NewHandlerSupport<Widget>We instantiateNewHandlerSupport<Widget>Class, our classWidgetThe widget class inherits the NewHandlerSupport function. The actual program execution process is the same as the first method, the only difference is that the class widgets do not need to redefine static functions related to memory processing.

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.