Generally, when calling the new operation, you do not need to worry about whether there is enough memory to make the operation successful. But as a perfectProgram, It is necessary to handle the case of insufficient memory.
By default, if the memory allocation fails, null is returned or an STD: bad_alloc exception is thrown, therefore, you need to check whether the returned value is null or wrap a try catch block on the new. However, apart from worrying about whether new is successful, we can use the set_new_handler function provided by C ++ to register a callback function after memory allocation fails. The set_new_handler function accepts a function pointer defined as follows:
Typedef void (* new_handler )();
When the new operation fails due to insufficient memory, if a new_handler is registered, the newly operation will call the handler you registered repeatedly, then re-allocate the memory (so you can use new_handler to release unnecessary memory to ensure the program runs smoothly ). Of course, if you do not register new_handler, it will throw an exception. For details, refer to the following section.Code:
While(P = malloc (size) = 0)
If(_ Callnewh (size) = 0)
{// Report no memory
Static ConstSTD: bad_alloc nomem;
_ Raise (nomem );
}
Return(P );
To sum up the usefulness of new_handler
1. Release the memory to ensure smooth execution of new operations
2. It is convenient to handle the exception of the new operation. You only need to register it once, and do not need to check or catch exceptions after each new operation.
The following is an example of the new operation:
1. When the memory is insufficient, write the log and release the unnecessary memory.
# Include "Stdafx. H"
# Include <Iostream>
# Include <Limits. h>
Using NamespaceSTD;
VoidMyhandler ()
{
Cerr <"Error doing new"<Endl;
// Some memory can be released here
}
Int_ Tmain (IntArgc, _ tchar * argv [])
{
Set_new_handler (myhandler );
IntMemoryneed = int_max;
Void* P = ::Operator New(Memoryneed );
Return0;
}
2. You can also change/remove the handler after calling new_handler for the first time to implement flexible memory allocation logic:
# Include "Stdafx. H"
# Include <Iostream>
# Include <Limits. h>
Using NamespaceSTD;
VoidMyhandler2 ()
{
Cerr <"New way to handler insufficient memory"<Endl;
//Remove the handler after the second execution and throw an exception using the default mechanism
Set_new_handler (null );
}
VoidMyhandler ()
{
Cerr <"Error doing new"<Endl;
//Set a new processing function after the first execution
Set_new_handler (myhandler2 );
}
Int_ Tmain (IntArgc, _ tchar * argv [])
{
Set_new_handler (myhandler );
IntMemoryneed = int_max;
Void* P = ::Operator New(Memoryneed );
Return0;
}
The output result is as follows: