Effective C ++ 2e Item5

zhaozj2021-02-11  181

Memory management

The management problem of memory involved in C can be attributed to two aspects: it is correctly obtained and used effectively. A good programmer will understand why these two issues are listed in this order. Because the execution is fast, the program is small if it does not execute it as if you think, it is not used. "Correctly" means correctly calling memory allocation and release programs; "Effectively Using" is a memory allocation and release program that is written a particular version. Here, "correctly" seems to be more important.

However, it is true that C has inherited a very serious headache from C, which is the hidden danger of memory. Virtual memory is a good invention, but virtual memory is limited, not everyone can grab it first.

In C, as long as the memory allocated by Malloc is not returned with Free, memory leaks will be generated. In C , the name of the perpetrator is replaced with new and delete, but the situation is basically the same. Of course, because there is a session of the designer, the situation is slightly improved because the designer function provides a place where the object to be destroyed provides a convenient call. But this also brought more troubles because New and Delete are implicitly modulated constructor and destructive functions. And because the New and Delete operators can be defined within the class and the class, this has brought complexity and increasing an error. The following terms (also Terms M8) will tell you how to avoid the universal problems.

Terms 5: Corresponding New and Delete To use the same form

What is wrong with the following statement? String * stringArray = new string [100];

...

DELETE STRINGARRAY;

Everything seems to be in order - a New corresponds to a delete, but hidden a lot of mistakes: the operation of the program will be unpredictable. At least, 99 of the 100 String objects pointing to StringArray will not be properly destroyed because their destructor will never be called.

Two things will occur when using New. First, the memory is assigned (via the Operator New function, see Terms 7-10 and Terms M8), then, one or more constructor is called for the assigned memory. When using Delete, there are two things happen: First, to call one or more destructor that will be released, then release memory (through the Operator Delete function, see Terms 8 and M8). There is an important issue for Delete: How many objects do you have to be deleted? The answer determines how many destructor will be called.

This problem is simple to say: The pointer to be deleted is a single object, or an object array? This is only you tell Delete. If you don't use parentheses when you use Delete, Delete will think is a single object, otherwise, it will think is an array: string * stringptr1 = new string;

String * stringptr2 = new string [100];

...

Delete stringptr1; // Delete an object delete [] stringptr2; // Delete an array of objects If you add "[]" before StringPtr1 "[]"? The answer is: That will be unpredictable; if you didn't add "[]" before StringPtr2? The answer is: unpredictable. And for a fixed type like INT, the result is not predictable, even if such types have no destructive functions. So, the rules that solve such problems are simple: if you call New [], use [] when calling Delete []. If you don't use [] when calling New, you don't use []. Keep in mind this rule when writing a class containing a pointer data member and providing multiple constructors. Because of this, you must use the same new form in the constructor of all initialization pointer members. Otherwise, what form of DELETE will be used in the destructor? Further explanation about this topic, see Terms 11.

This rule is also important for people who like to use Typedef, because the programmers who write TypedEF must tell others, after using NEW to create a type of TypedEf defined type, what form of delete is used to delete. For example: typedef string addresslines [4]; // A person's address, a total of 4 lines, one String, one string because addressLines is an array, use new: string * pal = new addressline; // Note "New AddressLines" Return string * , And // "New string [4]" must be in the form of array in the form of array: delete Pal; // Error!

Delete [] PAL; / / correct

In order to avoid confusion, it is best to prevent the array type TypeDefs. This is actually very easy, because the standard C library (see Terms 49) contains Stirng and Vector Templates, using them will reduce the demand for array to almost zero. For example, AddressLines can define a string (vector), ready to be a vector type.

转载请注明原文地址:https://www.9cbs.com/read-4482.html

New Post(0)