/****************************************************************/
/* Learning is a collaborative and shared style!
/* Author:atlas Email:[email protected]
* * Reprint Please indicate the source of this article:
* http://blog.csdn.net/wdzxl198/article/details/9059883
/****************************************************************/
Previous section review: portal
1.c++ Memory Management 1.1c language and C + + memory allocation 1.2 Distinguish heap, stack, static storage area |
1.3 Controlling memory allocations for C + +
A common problem in C + + is the allocation of memory, with emphasis on the improper use of new and delete and out of control. In general, C + + memory management is very easy and secure, when an object is eliminated, its destructor can safely release the allocated memory. So the frequent use of new and delete dynamic allocations can present some problems and the risk of heap fragmentation.
So, when you have to use new and delete, you have to control the memory allocations in C + +. You need to use a global new and delete to replace the system's memory-allocation, and a class-wide overload of new and delete.
A common way to prevent heap fragmentation is to allocate different types of objects from different fixed-size pools of memory. Overloading new and delete for each class provides such control.
Q: Why do I need to overload operator::new and operator::d elete? Although the standard library of C + + has provided us with a standard implementation of the new and delete operators, due to lack of specific analysis of specific objects, the system provided by default allocator in both time and space have a number of problems: The allocator is slow, and the allocation of small objects, space waste is more serious, Especially in special applications where there are significant limitations on efficiency or memory. For example, in embedded systems, due to memory constraints, frequent dynamic allocation of memory with variable size is likely to cause serious problems, even the risk of heap fragmentation; in game design, for example, efficiency is definitely a problem to be considered. The implementation of the standard new and delete operators has inherent efficiency flaws. At this point, we can resort to the overloads of the new and delete operators, which give the program more flexible memory allocation controls. In addition to improving efficiency, there are several possible reasons for overloading new and delete: A) detects memory errors in the code. b) Performance optimization b) obtain statistical data on memory usage. Note: The new and delete operators in C + + can not be overloaded, but can be overloaded in operator::new, which is only used to request memory and does not invoke the constructor initialization object! Remember, if you need to read more, check out the relevant documentation. In the book effective C + +, there are also explanations of why overloading is required, and it seems that overloading is necessary. For situations in which you need to overload new and delete, and how to overload the problem, you need to continue studying. |
See article-Recommendation 33: Carefully reload operator New/operator Delete |
(1) Overloading the global new and delete
The following code is in the "C + + Memory management technology Insider" Yes, limited to simple principle learning
1:void * operator new (size_t size)
2: {
3: void *p = malloc (size);
4: return (P);
5:}
6:void operator delete (void *p)
7: {
8: Free (P);
This code can replace the default operator to satisfy the memory allocation request. For the purpose of explaining C + +, we can also call malloc () and free () directly.
You can also overload the new and delete operators for a single class. This is where you can flexibly control the memory allocation of objects.
1:class TestClass {
2:public:
3: void * operator new (size_t size);
4: void operator delete (void *p);
5: //.
6:};
7:void *testclass::operator New (size_t size)
8: {
9: void *p = malloc (size);//Replace this with alternative allocator
Ten: return (P);
11:}
12:void testclass::operator Delete (void *p)
13: {
: Free (P);//Replace this with alternative de-allocator
15:}
This code is used for memory allocations for all TestClass objects. Further, any class that inherits from TestClass also takes this approach, unless it itself overloads the new and delete operators. By overloading the new and delete operators, you are free to use different allocation strategies to allocate different class objects from different memory pools.
(2) overloading new[] and delete[for a single class)
You must be careful about assigning objects to arrays. You may want to invoke the new and delete operators that you have overloaded, but that is not the case. The memory requests are directed to the global new[] and delete[] operators, which are derived from the system heap.
C + + allocates memory allocations for an array of objects as a separate operation, unlike a single object's memory allocation. To change this, you also need to overload the new[] and delete[] operators.
1:class TestClass {
2:public:
3: void * operator new[] (size_t size);
4: void operator delete[] (void *p);
5: //.
6:};
7:void *testclass::operator new[] (size_t size)
8: {
9: void *p = malloc (size);
Ten: return (P);
11:}
12:void testclass::operator delete[] (void *p)
13: {
: Free (P);
15:}
16:int Main (void)
17: {
: TestClass *p = new TESTCLASS[10];
: //... etc...
: delete[] p;
Note, however: for most implementations of C + +, the number of arguments in the new[] operator is the size of the array plus the number of extra bytes that are stored in the object. This is important to consider in your memory allocation mechanism. You should try to avoid assigning an array of objects so that your memory allocation strategy is simple.
Also: for overloaded new and delete or new[] and delete[], there are a number of things to consider, such as error handling mechanisms, inheritance, polymorphism, and so on. Confined to space, will be in a future article in detail, buy a foreshadowing here.
(You can refer to an article new, delete (new[], delete[]) operator overload).
1.4 Basic requirements for memory management
If only the allocation and release are considered, the basic requirements for memory management are "no heavy leaks": Neither delete nor delete is omitted. Also say that we often say new/delete to pair, "pairing" is not only the number of equal, but also implies that the new and delete calls themselves to match, not "the owner borrowed something West home". For example:
- The memory allocated by the system default malloc () is given to the system default free () to release;
- Objects created with the system's default new expression are left to the system's default delete expression for destruction and release;
- Objects created with the system default new[] expression are given to the system default delete[] expression to be disposed of and released;
- With the system default:: operator new () allocated memory to the system default:: operator delete () to release;
- Objects created with placement new are to be placement delete (let's say so for ease of expression) to deconstruct (in fact, call destructors directly);
- The memory allocated from a memory Pool A is returned to this memory pool.
If custom New/delete, then follow the rules. See effective C + + related terms. Doing so is the basic skill of every C + + developer.
1.5 common memory errors and their countermeasures
A memory error is a very troublesome thing to happen. These errors are not automatically discovered by the compiler and are usually captured when the program is running. And most of these errors are not obvious symptoms, and the hidden, increased the difficulty of error. Sometimes the user angrily to find you, the program did not have any problems, you go, wrong and attack.
Common memory errors include the following:
(1) The memory allocation was unsuccessful, but it was used.
Novice programmers often make this mistake because they are unaware that the memory allocation will not succeed. A common workaround is to check if the pointer is null before using memory. If the pointer p is an argument to a function, it is checked with an assert (P!=null) at the entrance of the function. If you are using malloc or new to request memory, you should use if (p==null) or if (P!=null) for error-proof handling.
(2) The memory allocation succeeds, but it is not initialized to reference it.
There are two main causes of this error: one is the idea of no initialization, and the other is to mistakenly assume that the default initial value of the memory is all zero, resulting in a reference to the initial error (for example, an array). There is no uniform standard for what the default initial value of memory is, although sometimes it is a zero value and we would rather believe it to be credible. So no matter how to create an array, do not forget to assign the initial value, even if it is assigned 0 values can not be omitted, do not bother.
(3) The memory allocation succeeds and has been initialized, but the operation crosses the memory boundary.
For example, the use of arrays often occurs when the subscript "more 1" or "less 1" operation. Especially in a For loop statement, the number of loops can be easily mistaken, resulting in array operations being out of bounds.
(4) forgot to release memory, causing memory leak.
The function that contains this error loses one piece of memory each time it is called. At first, the system has plenty of memory and you can't see the error. One time the program suddenly died, the system appears prompt: memory exhaustion. Dynamic memory application and release must be paired, the program malloc and free use must be the same number, otherwise there must be errors (new/delete).
(5) Release the memory and continue to use it.
There are three types of cases:
(a) The object invocation relationship in the program is too complex, it is difficult to know whether an object has freed the memory, at this time should redesign the data structure, fundamentally solve the chaos of object management.
(b) The return statement of the function is incorrectly written, and be careful not to return a pointer or reference to "stack memory" because the memory is automatically destroyed at the end of the function body.
(c) After releasing memory with free or delete, the pointer is not set to null. Causes the "wild pointer" to be produced.
Common memory error countermeasures are as follows:
After rule 1 has requested memory with malloc or new, you should immediately check that the pointer value is NULL. Prevents the use of memory with a pointer value of NULL.
Rule 2 Do not forget to assign an initial value to both arrays and dynamic memory. Prevents memory that is not initialized from being used as the right value.
"Rule 3" avoids array or pointer subscript out of bounds, especially beware of "more 1" or "less 1" operations.
"Rule 4" the request and release of dynamic memory must be paired to prevent a memory leak.
"Rule 5" after releasing memory with free or delete, immediately set the pointer to NULL to prevent the "wild pointer" from being produced.
This part of the study notes, which have a lot of knowledge, such as new and delete overload, memory error situation and processing mechanism, and so on, learning.
Reference: C + + memory management learning framework;
Atlas
EDIT:2013/6/8 22:31
C + + Memory Management Learning notes (2)