Item 16: The New and delete pairs must use the same form.
By Scott Meyers
Translator: fatalerror99 (itepub's nirvana)
Release: http://blog.csdn.net/fatalerror99/
What is the problem with the following code?
STD: string * stringarray = new STD: String [100];
...
Delete stringarray;
Everything looks normal. A Delete is also used for new. However, there is still something completely wrong. The action of the program is undefined. At least 99 of the 100 string objects pointed to by stringarray are unlikely to be completely destroyed, because their Destructors (destructor) may not be called at all.
When you useNew Expression(New expression) (that is, using new to dynamically create an object), two things will happen. First, the memory is allocated (through a function named operator New-see Items 49 and 51 ). Second, call one or more constructors for the memory ). When you useDelete expression(Delete expression) (that is, using delete), there are two other things: calling one or more Destructors (destructor) for these memories ), then the memory is recycled (through a function named operator Delete-see item 51 ). There is a big problem with Delete: How many objects exist in the memory to be deleted? The answer to this question will determine how many Destructors must be called.
In fact, the question is simple: will the pointer to be deleted point to a single object (single object) or an array of objects (Object array )? This is a key issue because the memory layout of a single object is usually different from that of an array. In details, the memory layout of an array usually contains the size of the array, which makes it easier for Delete to know how many Destructors (destructor) are to be called. The memory of a single object lacks this information. You can think that different memory la s look like, that N is the size of the array:
Of course this is just an example. The compiler does not have to implement this, although many of them do.
When you use Delete For a pointer, the only way for Delete to know whether the array size information exists is to tell it. If you add square brackets to your delete usage, delete assumes that the pointer points to an array. Otherwise, it is assumed to point to a single object (single object ).
STD: string * stringptr1 = new STD: string;
STD: string * stringptr2 = new STD: String [100];
...
DeleteStringptr1; // delete an object
Delete []Stringptr2; // delete an array of Objects
What happens if you use the "[]" form for stringptr1? The result is undefined, but it is unlikely to be a good thing. For example, in the layout, delete reads some memory content and regards it as the size of an array. Then it starts to call so many Destructors (destructor ), regardless of the memory on which it operates, it is not only an array, but may not have any objects (objects) of the type that it can analyze ).
What happens if you do not use the "[]" form for stringptr2? It is also undefined, but you will see that it will cause too few Destructors (destructor) to be called. In addition, for built-in types (built-in types) similar to ints, the results are also undefined (and sometimes harmful), even if such types do not have Destructors (destructor ).
The rule is simple: if you use [] in a new expression, you must also use [] in the corresponding Delete expression. If you do not use [] in a new expression, do not use [] In a matched Delete expression.
When you write a class that contains a pointer to dynamically allocated memory (dynamically allocated memory) and provides multiple constructors, it is especially important to keep this rule in mind, because at that time you must be careful to use the newSame Form(In the same form) initialize the pointer member. If you do not do this, how do you know which form of Delete is used in your destructor (destructor?
This rule is also worth noting for people with typedef-inclined (typedef hobby), because it means that the author of a typedef must record in the document: when a typedef type objects (object) is generated using new, which form of Delete should be used. For example, consider the typedef:
Typedef STD: String addresslines [4]; // a person's address has 4 lines,
// Each of which is a string
Because addresslines is an array, the use of new here,
STD: string * pal = new addresslines; // note that "New addresslines"
// Returns a string *, just like
// "New String [4]" wowould
It must be matched by the delete array format:
Delete pal; // undefined!
Delete [] pal; // fine
To avoid this confusion, avoid using typedef for array types (array type. That's easy, because the standard C ++ Library (see item 54) contains string and vector, and those templates (templates) will dynamically allocate arrays to dynamically allocated arrays) to almost zero. For example, addresslines can be defined as a strings vector, that is, the type is vector <string>.
Things to remember
- If you use [] in the new expression, you must also use [] in the corresponding Delete expression. If [] is not used in the new expression, you do not need to use [] in the corresponding Delete expression.