The use of the 6.2 new and delete operator operator new appears to be a single operation, like this:
int *pi = new int (5);
But in fact it is done by the following two steps:
1. Configure the required memory with the appropriate new operator function entity:
Call the new operator in the function library int *pi = __new (sizeof (int));
2. Set an initial value for the configured object:
*pi = 5;
Further, the initialization operation should be performed after the memory configuration succeeds (via the new operator):
The two detach steps of the new operator//given:int *PI = new int (5);//override declares int *pi;if (pi = __new (sizeof (int))) *pi = 5;
The delete operator is similar to the case when the programmer writes:
Delete pi;
If the value of pi is 0,c++ the language will require the delete operator to have no action. Therefore, the compiler must construct a layer of protection for this call:
if (pi! = 0) __delete (PI);
Note that pi is not automatically cleared to 0, so follow-up behavior like this:
No good definition, but legal if (pi && *pi = = 5) ...
Although there is no good definition, it may (or may not) be evaluated as true. This is because the memory that the pi points to is changed or reused, which may or may not occur.
The life of the object that Pi refers to is terminated by the delete, so any subsequent reference operation to the PI no longer guarantees good behavior and is therefore considered a bad procedural style. However, it is still possible to use the PI as a pointer (although its use is limited), for example:
Pi still points to legal space//Even if the object stored in it is no longer legal if (pi = = sentine1) ...
Here, the difference between using the pointer pi and the object that the pi refers to is that the declaration is over. Although the object on this address is no longer legal, the address itself still represents a legitimate program space. So pi can continue to be used, but only in restricted cases, much like a void * pointer case .
Use constructor to configure a class object in a similar situation, such as:
Point3D *origin = new Point3D;
is converted to:
Point3D *origin;if (origin = __new (sizeof (Point3D))) origin = Point3D::P Oint3d (Origin);
If exception handling, destructor should be placed in a try section. Exception handler calls the delete operator and then drops the exception again.
General Lirary the implementation of the new operator is straightforward, but there are two ingenious things to consider:
extern void *operator New (size_t size) { if (size = = 0) size = 1; void *last_alloc; while (!) ( Last_alloc = malloc (size)) { if (_new_handler) (*_new_handler) (); else return 0; } return last_alloc;}
Although it is legal to write:
New T[0];
But language requires that every call to new must return a unique pointer. The traditional way to solve this problem is to return a pointer to a memory chunk that defaults to 1 byte (which is why the size in the program code is set to 1). Another interesting thing about this implementation technique is that It allows the user to provide a _new_handler () function of their own. That's why every loop calls _new_handler ().
The new operator is actually always done with standard C malloc (), although there is no provision for this to happen. In the same case, the delete operator is always done with the standard C free ():
extern void operator delete (void *ptr) { if (PTR) free ((char *) ptr);}
For the new semantics of the array, when this is written:
int *p_array = new Int[5];
, Vec_new () is not really called because its main function is to execute the default constructor on every element of the array of class objects. The new operator function is called:
int *p_array = (int *) __new (5 * sizeof (int));
The same situation, if written:
struct SIMPLE_AGGR {float f1, F2;};
Simple_aggr *p_aggr = new Simple_aggr[5];
Vec_new () will not be called. Why? Because Simple_aggr does not define a constructor or destructor, configuring an array and clearing the operations of the P_AGGR array simply gets the memory and frees the memory. These operations are performed by the The new and delete operators are more than sufficient to complete.
However, if the class definition has a default constructor, some versions of Vec_new () are called to configure and construct an array of class objects, such as this equation:
Point3D *p_array = new POINT3D[10];
It is usually compiled as:
Point3D *p_array;
P_array = vec_new (0, sizeof (POINT3D), ten, &point3d::P Oint3d, &point3d::~point3d);
During the construction of an individual array element, Exception,destructor is passed to Vec_new () if it occurs. Only elements that have been properly constructed need to be destructor, because their memory is already configured, Vec_new () It is the responsibility to release those memory when exception occurs.
You do not need to specify the number of array elements at Delete, as follows:
delete []p_array;
The search for an array dimension has a great effect on the efficiency of the delete operator, and it leads to the compromise that the compiler looks for the dimensions of the array only when the brackets appear, otherwise it assumes that only a single object is to be deleted. If the programmer does not provide the necessary brackets, like this:
Delete P_array;
Then only the first element is deconstructed and the other elements still exist.
How should the number of elements be recorded? One obvious way is to configure an extra word for each chunk of memory that vec_new () returns, and then to put the number of elements in that word. This is usually called a cookie. However, the Sun compiler maintains a " Union array, place the pointer and the size. It also maintains the destructor address in this array.
The cookie policy has a generally worrying topic, which is that if a bad pointer is handed over to Delete_vec (), the cookie taken out is naturally illegal. An illegal number of elements and a bad starting address, Causes the destructor to be implemented in an unintended area in an unexpected number of times, but under the "Union array" policy, the possible result of a bad pointer is simply the number of elements that have been incorrectly removed.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
C + + object model--new and delete operators (chap. sixth)