1:C ++ standard: an allocation function shall be a class member function or a global function; A program is ill-formed if an allocation function is declared in a namespace scope other than global scope or declared static in global scope.
It must be a global function or a class member function, but not a namespace or static global function outside the global.
2: New operator action
For the following code:
Foo * P = new (parameter 1, parameter 2 ,...... ) Foo (......);
...... Other code ......
Delete P;
The compiler generates the following code:
Call P = Operator new (size required by size_t, parameter 1, parameter 2 ,...... ); // It is possible to throw STD: bad_alloc, but it does not need to be captured in new operator.
If foo is constructed, no exception will be thrown. // The Foo constructor explicitly declares throw ()
Construct Foo (parameter 1, parameter 2,…) at the point P ,......);
Return P;
Otherwise
Try
{
Construct Foo (parameter 1, parameter 2,…) at the point P ,......);
Return P;
}
Catch (...)
{
Call operator Delete (void * P, parameter 1, parameter 2 ,...... );
Throw;
}
...... Other code ......
Call operator Delete (void * P );
From the above description, we can see two points:
A. Except for the first parameter, operator Delete with the same parameters as operator new is called a matched operator Delete.
B. The matched operator Delete is called only when operator new is successful and the object construction fails. Operator Delete (void * P) is always called elsewhere ).
(If not, the compiler binds each P to the operator Delete address that matches the operator new called at the beginning, as well as the real parameters in the original call. Khan !!! )
3: Operator new pseudocode in the global format:
Void * operator new (size_t size) // includes other forms
{
If (0 = size) // note
Size = 1;
While (1)
{
Allocate size bytes of memory;
If (allocated successfully)
Return refers to the memory pointer;
New_handler globalhandler = set_new_handler (0 );
Set_new_handler (globalhandler );
If (globalhandler)
(* Globalhandler )();
Else
Throw STD: bad_alloc ();
}
}
Void operator Delete (void * Raw)
{
If (0 = raw) // note
Return;
...
}
It must be noted that the compiler itself implies a void * operator new (size_t), so the global operator new must be overloaded with other parameters to show the difference.
Generally, three methods are reloaded when the overload assignment function is used, namely void * operator new (size_t ,...... ), Void operator Delete (void *,...... ), And the general form of void operator Delete (void *).
4. Functions of set_new_handler
Set_new_handler sets a function, which is called when the memory allocation fails. For details, see the code in 3.
From the code in 3, we can see that new_handler must have an active exit function, otherwise it will lead to an internal endless loop of operator new. Therefore, the general form of newhandler is:
Void mynewhandler ()
{
If (it is possible that operator new is successful (for example, some memory is released ))
{
Doing something that may make operator new successful
Return;
}
// Actively exit
Or abort/exit to exit the program directly.
Or set_new_handler (Other newhandler );
Or set_new_handler (0)
Or throw bad_alloc () or derived class // This is better, close the program rudely, and do not change other settings
}
It should be noted that there is no set_new_handler in the class form, but it doesn't matter either. You can write it yourself. (See article 7 of Objective C ++ 2E)
5. Operator new pseudocode in class form:
Struct Base
{
...
Static void * operator new (size_t size );
Static void operator Delete (void * Raw );
};
Void * base: Operator new (size_t size)
{
If (sizeof (base )! = Size) // note
Return: Operator new (size );
Similar to 3 // note that "there is no set_new_handler in the class form"
}
Void base: Operator Delete (void * Raw)
{
If (sizeof (base )! = Size) // note
{
: Operator Delete (raw );
Return;
}
Same as 3
}
Source: http://blog.vckbase.com/bruceteen/archive/2009/05/27/37427.html