C/C ++ uses the Lu key tree to implement smart pointers and check for memory leaks

Source: Internet
Author: User

Welcome to Lu Program Design

C/C ++ uses the Lu key tree to implement smart pointers and check for memory leaks

1 Description

To demonstrate this example, you must download the Lu32 script system. In this example, the header files lu32.dll, lu32.lib, and C ++ are required. We believe you will find and use these files correctly.

Use the C/C ++ compiler to create a console application. Copy the sample code in this article and compile and run it.

2. smart pointer and Lu implementation

Since the C/C ++ language does not have an automatic memory reclaim mechanism, every time the programmer malloc/new memory comes out, it must be manually free/delete. Because the program process is too complex, it is easy for programmers to forget free/delete, resulting in Memory leakage. C ++ uses smart pointers to effectively alleviate such problems, such as std: auto_ptr, boost: scoped_ptr, boost: shared_ptr, boost: scoped_array, and boost :: shared_array, boost: weak_ptr, boost: intrusive_ptr, etc.

In fact, the C/C ++ program uses the Lu script's key tree system to solve such problems, and the programmer can easily find out which memory has forgotten the free/delete. After reading this article, you can use the Lu script system to check whether your C/C ++ program has memory leakage.

For more information about the Lu script key tree system, see the Lu programming guide and the tutorial C/C ++ using the Lu script string key tree.

3Code

Code 1: Implement smart pointer

# Include
 
  
# Include
  
   
# Include "lu32.h" # pragma comment (lib, "lu32.lib") using namespace std; # define key_Simple (luPriKey_User-20) // lock the Private Key # define imax5 // maximum number of private key values void _ stdcall Del_Simple (void * me ); // destroy the Simple function class Simple // compile a Simple class to help test {public: int number; // data bool bDelete; // to help test new data, when the object is initialized, bDelete = false; when the object is destroyed, bDelete = trueSimple (int param = 0) {// Add the following lines of code void * me to the class initialization function, * NowKey = NULL; // to prevent the compiler from issuing warnings for initialization, You do not actually need me = this; InsertKey (Char *) & (me), sizeof (luVOID), key_Simple, this, Del_Simple, NULL, 1, NowKey ); // register the key value bDelete = false in the Lu key tree; number = param; cout <"Simple:" <number <endl ;};~ Simple () {// Add the following lines of code in the class initialization function void * me; if (! BDelete) // If you manually delete {bDelete = true; me = this; DeleteKey (char *) & (me), sizeof (luVOID), key_Simple, Del_Simple, 0 ); // Delete the key value} cout In the Lu key tree <"~ Simple: "<number <endl ;};}; void _ stdcall Del_Simple (void * me) // destroy the Simple function and register it with the Lu system, to achieve automatic destruction of Simple {Simple * pSimple; pSimple = (Simple *) me; if (pSimple-> bDelete = false) // if the user forgets delete {pSimple-> bDelete = true; delete pSimple; // This is the Lu system automatic delete} LuData _ stdcall OpLock_Simple (luINT m, LuData * Para, void * hFor, int theOperator) // Simple operator overload function {LuData a;. BType = luStaData_nil;. VType = luStaData_nil;. x = 0; // No Simp Le-type objects for calculation, the total return nilreturn a;} void main (void) {Simple * pSimple [imax]; int I; if (! InitLu () return; // initialize LuLockKey (key_Simple, Del_Simple, OpLock_Simple); // Add a lock key to the Lu key tree and only store the Simple type for (I = 0; I
   
    


Running result:

Simple: 0
Simple: 1
Simple: 2
Simple: 3
Simple: 4

--- C ++ delete about 1/2 objects ---

~ Simple: 0
~ Simple: 1

--- Lu system unlock key and destroy all objects ---

~ Simple: 2
~ Simple: 4
~ Simple: 3

Code 2: Search for unreleased objects (memory)

# Include
     
      
# Include
      
       
# Include "lu32.h" # pragma comment (lib, "lu32.lib") using namespace std; # define key_Simple (luPriKey_User-20) // lock the Private Key # define imax5 // maximum number of private key values void _ stdcall Del_Simple (void * me ); // destroy the Simple function class Simple // compile a Simple class to help test {public: int number; // data bool bDelete; // to help test new data, when the object is initialized, bDelete = false; when the object is destroyed, bDelete = trueSimple (int param = 0) {// Add the following lines of code void * me to the class initialization function, * NowKey = NULL; // to prevent the compiler from issuing warnings for initialization, You do not actually need me = this; InsertKey (Char *) & (me), sizeof (luVOID), key_Simple, this, Del_Simple, NULL, 1, NowKey ); // register the key value bDelete = false in the Lu key tree; number = param; cout <"Simple:" <number <endl ;};~ Simple () {// Add the following lines of code in the class initialization function void * me; if (! BDelete) // If you manually delete {bDelete = true; me = this; DeleteKey (char *) & (me), sizeof (luVOID), key_Simple, Del_Simple, 0 ); // Delete the key value} cout In the Lu key tree <"~ Simple: "<number <endl ;};}; void _ stdcall Del_Simple (void * me) // destroy the Simple function and register it with the Lu system, to achieve automatic destruction of Simple {Simple * pSimple; pSimple = (Simple *) me; if (pSimple-> bDelete = false) // if the user forgets delete {pSimple-> bDelete = true; delete pSimple; // This is the Lu system automatic delete} LuData _ stdcall OpLock_Simple (luINT m, LuData * Para, void * hFor, int theOperator) // Simple operator overload function {LuData a;. BType = luStaData_nil;. VType = luStaData_nil;. x = 0; // No Simp Le-type objects for calculation, Total Return nilreturn a;} int _ stdcall GetKeySimpleValue (char * KeyStr, int ByteNum, void * KeyValue) // enumerate all objects of the specified key value type in the Lu system {Simple * pSimple; pSimple = (Simple *) KeyValue; cout <"Simple-> number: "<pSimple-> number <endl; return 1 ;}void main (void) {Simple * pSimple [imax]; int I; char KeyStr [sizeof (luVOID) + 1]; // used to enumerate undestroyed objects. The length is greater than the pointer length by 1if (! InitLu () return; // initialize LuLockKey (key_Simple, Del_Simple, OpLock_Simple); // Add a lock key to the Lu key tree and only store the Simple type for (I = 0; I
       
        


Running result:

Simple: 0
Simple: 1
Simple: 2
Simple: 3
Simple: 4

--- C ++ delete about 1/2 objects ---

~ Simple: 0
~ Simple: 1

--- Use Lu to enumerate unreleased objects ---

Simple-> number: 2
Simple-> number: 4
Simple-> number: 3

--- Lu system unlock key and destroy all objects ---

~ Simple: 2
~ Simple: 4
~ Simple: 3

Code 3: One efficiency test with no Lu Buffer Used

# Include
         
          
# Include
          
           
# Include
           
            
# Include "lu32.h" # pragma comment (lib, "lu32.lib") using namespace std; # define key_Simple (luPriKey_User-20) // lock the Private Key # define imax10 // The maximum number of private key values. When modifying this data, you must modify the following number of cycles kmaxint kmax = 100000; // number of cycles void _ stdcall Del_Simple (void * me); // destroy the Simple function class Simple // compile a Simple class help test: Use the Lu system {public: int number; // data bool bDelete; // to help test new data, bDelete = false during object initialization and bDelete = trueSimple (int param = 0) during object destruction) {// Add the following lines of code void * me to the class initialization Function, * NowKey = NULL; // to prevent the compiler from issuing a warning for initialization, You do not actually need me = this; InsertKey (char *) & (me), sizeof (luVOID ), key_Simple, this, Del_Simple, NULL, 1, NowKey); // register the key value bDelete = false in the Lu key tree; // initialization code number = param ;};~ Simple () {// Add the following lines of code in the class initialization function void * me; if (! BDelete) // If you manually delete {bDelete = true; me = this; DeleteKey (char *) & (me), sizeof (luVOID), key_Simple, Del_Simple, 0 ); // Delete the key value in the Lu key tree} // other code of the object to be destroyed };}; void _ stdcall Del_Simple (void * me) // destroy the Simple function, register to the Lu system to automatically destroy Simple {Simple * pSimple; pSimple = (Simple *) me; if (pSimple-> bDelete = false) // if the user forgets delete {pSimple-> bDelete = true; delete pSimple; // This is the Lu system automatic delete} LuData _ stdcall OpLock_Simple (luINT m, LuData * Para, void * hFo R, int theOperator) // operator overload function of Simple {LuData a;. BType = luStaData_nil;. VType = luStaData_nil;. x = 0; // The nilreturn a;} class SimpleCpp is always returned for an operation on a Simple object. // compile a Simple class help test: Do not use the Lu system {public: int number; // data SimpleCpp (int param = 0) {// initialization code number = param ;};~ SimpleCpp () {// other code for object destruction} ;}; void main (void) {Simple * pSimple [imax]; SimpleCpp * pSimpleCpp [imax]; int I, j; clock_t start, end; start = clock (); for (j = 0; j
            
             


Running result:

--- C/C ++ system running time: 218 ms.
--- C/C ++ Lu composite system run time: 10578 ms.

Code 4: Efficiency Test 2. Use the Lu Buffer

# Include
              
               
# Include
               
                
# Include
                
                 
# Include "lu32.h" # pragma comment (lib, "lu32.lib") using namespace std; # define key_Simple (luPriKey_User-20) // lock the Private Key # define imax10 // The maximum number of private key values. When modifying this data, you must modify the following number of cycles kmaxint kmax = 100000; // number of cycles void _ stdcall Del_Simple (void * me); // destroy the Simple function class Simple // compile a Simple class help test: Use the Lu system {public: int number; // data bool bDelete; // to help test new data, bDelete = false during object initialization and bDelete = trueSimple (int param = 0) during object destruction) {// Add the following lines of code void * me to the class initialization Function, * NowKey = NULL; // to prevent the compiler from issuing a warning for initialization, You do not actually need me = this; InsertKey (char *) & (me), sizeof (luVOID ), key_Simple, this, Del_Simple, NULL, 1, NowKey); // register the key value bDelete = false in the Lu key tree; // initialization code number = param ;};~ Simple () {// Add the following lines of code in the class initialization function void * me; if (! BDelete) // If you manually delete {bDelete = true; me = this; DeleteKey (char *) & (me), sizeof (luVOID), key_Simple, Del_Simple, 0 ); // Delete the key value in the Lu key tree} // other code for destroying the object}; Simple * NewSimple (int param = 0) // design a dedicated function to generate the Simple function {Simple * pSimple; char keyname [sizeof (luVOID)]; pSimple = (Simple *) GetBufObj (key_Simple, keyname ); // first try to obtain a Simple object from the buffer if (pSimple) // obtain the object and initialize {pSimple-> number = param ;} else // generate a new object and initialize {pSimple = new Simple (param);} return pSimp Le;} void _ stdcall Del_Simple (void * me) // destroy the Simple function and register it with the Lu system to automatically destroy Simple {Simple * pSimple; pSimple = (Simple *) me; if (pSimple-> bDelete = false) // if the user forgets delete {pSimple-> bDelete = true; delete pSimple; // This is Lu system automatic delete} LuData _ stdcall OpLock_Simple (luINT m, LuData * Para, void * hFor, int theOperator) // The Simple operator overload function {LuData; a. BType = luStaData_nil;. VType = luStaData_nil;. x = 0; // The nilreturn a;} is returned for all Simple objects ;} Class SimpleCpp // compile a simple class help test: Do not use Lu system {public: int number; // data SimpleCpp (int param = 0) {// initialization code number = param ;};~ SimpleCpp () {// other code for object destruction} ;}; void main (void) {Simple * pSimple [imax]; SimpleCpp * pSimpleCpp [imax]; int I, j; clock_t start, end; start = clock (); for (j = 0; j
                 
                  


Running result:

--- C/C ++ system running time: 234 ms.
--- C/C ++ Lu composite system run time: 125 ms.

4Function Description

In this example, seven output functions of Lu are used: InitLu, FreeLu, InsertKey, and DeleteKey, the LockKey function is used to enumerate the EnumKey of the key value. The GetBufObj function of an object is obtained from the buffer pool. For more information about these functions, see the Lu programming guide.

5Difficulties

Code 1 implements smart pointers. For C/C ++ programs, you only need to add several lines of code to the class constructor and destructor. Of course, it is essential to load the Lu core database, lock and unlock the specified data type.

Code 2 checks the memory leakage of C/C ++ programs based on Code 1. Only the EnumKey function with one enumerated key value is added.

Code 3 tests the generation and destruction efficiency of objects using the Lu smart pointer and compares it with C/C ++. The results show that when the Lu buffer pool is not used, the efficiency of C/C ++ and Lu composite programs is about 1/50 of that of C/C ++ programs.

Code 4 still tests the generation and destruction efficiency of objects using the Lu smart pointer. However, when the Lu buffer pool is used, the result shows that when the Lu buffer pool is used, the efficiency of C/C ++ and Lu composite programs is twice that of C/C ++ programs. The price for using the Lu buffer pool is that you must design a function to generate an object to replace the new operator. When destroying an object, do not delete it directly. Instead, use the DeleteKey function of the Lu system. In addition, code 4 tests the generation and destruction of objects in a small scope (the number of objects imax = 10), making full use of the Lu buffer pool, which is in line with general program running conditions; if you modify imax = 1000 and kmax = 1000 (number of cycles) in code 4 Before testing, you will find that, the efficiency of C/C ++ and Lu composite programs degrades to code 3.

6 others

You may have noticed that my contact information is below. If you have any questions or suggestions, please feel free to contact me.

Copyright?Lu Program Design2002-2013, retain all rights
E-mail: forcal@sina.com QQ: 630715621
Last Updated: December 1, January 03, 2014

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.