1. Development background:
When programming with VC in Windows, we usually need to run the program in debug mode, and the debugger will print out memory information that is allocated on the heap while the program is running, including the code filename, line number, and memory size, when exiting the program. This feature is a built-in mechanism provided by the MFC Framework, encapsulated within its class structure system.
Under Linux or Unix, our C + + program lacks the means to detect memory information, and can only use the top command to observe the total dynamic memory of the process. And when the program exits, we cannot learn any memory leaks. In order to better assist the program development under Linux, we designed and implemented a memory detection subsystem in our Class library project. The basic principles of new and delete in C + + are described below, and the implementation principle of the memory detection subsystem, the techniques of implementation, and the advanced topics of memory leak detection are discussed.
2. The principle of new and delete
When we write new and delete in the program, we actually call the new operator and delete operator built into the C + + language. The so-called language built-in means that we can not change its meaning, its function is always the same. In the case of new operator, it always allocates enough memory before invoking the corresponding type's constructor to initialize the memory. The delete operator always invokes the destructor of that type and then frees the memory (Figure 1). The fact that we can exert influence is the method of allocating and freeing memory during the execution of new operator and delete operator.
The name of the function called by new operator for allocating memory is operator new, whose usual form is void * operator new (size_t size); The return value type is void*, because this function returns an unprocessed (raw) pointer to the uninitialized memory. The parameter size determines how much memory is allocated, and you can add additional parameters to the overloaded function operator new, but the first parameter type must be size_t.
Delete operator The name of the function called to free memory is operator delete, which is usually in the form of void operator delete (void *memorytobedeallocated) That frees the area of memory that the incoming parameter points to.
One problem here is that when we call the new operator allocate memory, there is a size parameter that indicates how much memory needs to be allocated. But when the delete operator is called without a similar argument, how does the delete operator know the size of the memory block that the pointer is to be freed from? The answer is: for a system-owned data type, the language itself can distinguish the size of the memory block, and for custom data types (such as our custom classes), the operator new and operator deletes need to pass information to each other.
When we use operator new to allocate memory for a custom type object, we actually get more memory than the actual object, which, in addition to storing the object data, needs to record the size of the memory, a method called a cookie. The implementation of this point differs depending on the compiler. (for example, MFC chooses to store the actual data for the object in the header of the allocated memory, while the following section stores the boundary flag and memory size information.) G++ uses the first 4 of the allocated memory to store the relevant information, while the following memory stores the object's actual data. When we use the delete operator for a memory release operation, the delete operator can correctly release the block of memory that the pointer points to according to the information.
The above discussion is about memory allocation/release of a single object, when we allocate/release memory for an array, although we still use the new operator and delete operator, but the internal behavior is different: new operator calls operator new Array of brothers-operator New[], and then call the constructor for each of the group members. The delete operator first calls the destructor on each array member, and then calls operator delete[] to free the memory. Note that when we create or release an array of custom data types, the compiler uses the compiler-related cookie technology to be able to identify the size of the memory blocks that are needed to be freed in operator delete[.
To sum up, if we want to detect memory leaks, we must record and analyze the memory allocation and release in the program, which means we need to overload operator New/operator New[];operator Delete/operator delete[] Four global functions to intercept the memory operation information we need to verify.