C ++ auto_ptr smart pointer and auto_ptr smart pointer
C ++ auto_ptr smart pointer
In the header file memory, this type is imported through # include <memory> when the program is activated. Next, we will explain the role and use of this smart pointer.
Usage:
Auto_ptr <type> ptr (new type (); this is the definition form of the pointer, where type is the type pointed to by the pointer, ptr is the name of the pointer.
For example, if the type is int, the specific definition is as follows:
Auto_ptr <int> ptr (new int (4 ));
For example, if the type is map <int, vector <int>, the specific definition is as follows:
Auto_ptr <map <int, vector <int> ptr (new map <int, vector <int> ());
Of course, you can define and assign values first, as shown below:
Auto_ptr <map <int, int> ptr;
Ptr = auto_ptr <map <int, int> (new map <int, int> ());
Role 1: Ensure that an object can only be pointed to by a smart pointer of this type at a time, that is, the ownership of the object.
Role 2: The function of automatic release of the object to be pointed to. For details, see the following code.
Code snippet 1:
# Include <iostream> # include <string. h> # include <memory> # include <string> # include <Windows. h >#include <map >#include <ctime> # include <vector> using namespace std; # define MAXN 20000000 class test_ptr {public: map <int, int> * p; test_ptr () {p = new map <int, int> (); for (int I = 0; I <MAXN; I ++) p-> insert (make_pair (I, i) ;}}; int main (int argc, char * argv []) {for (int I = 0; I <100; I ++) {Sleep (1000); cout <I <endl; // number of times test_ptr * tmp = new test_ptr () ;}system ("pause"); return 0 ;}
In some cases, we may write the above Code and run it to find memory overflow. Some experienced programmers may make the following changes:
Code snippet 2:
#include <iostream>#include <string.h>#include <memory>#include <string>#include <Windows.h>#include <map>#include <ctime>#include <vector>using namespace std;#define MAXN 20000000class test_ptr{public: map<int,int> *p; test_ptr() { //p = auto_ptr<map<int,int> > (new map<int,int>()); p = new map<int,int>(); for(int i = 0;i<MAXN;i++) p->insert(make_pair(i,i)); } ~test_ptr() { delete p; } };int main(int argc,char *argv[]){ for(int i = 0;i<100;i++) { Sleep(1000); cout << i << endl; test_ptr * tmp = new test_ptr(); } system("pause"); return 0;}
The memory release code is added to the destructor of the test_ptr class. However, the local pointer defined in the main function does not automatically call the Destructor when the local pointer fails, in this case, memory leakage may also occur. Of course, if careful programmers can add a delete tmp after test_ptr * tmp = new test_ptr (), the memory can be released without memory leakage. However, in some cases, it is easy to miss writing. To solve this problem, auto_ptr can play a role.
Code snippet 3:
# Include <iostream> # include <string. h> # include <memory> # include <string> # include <Windows. h >#include <map >#include <ctime> # include <vector> using namespace std; # define MAXN 20000000 class test_ptr {public: map <int, int> * p; test_ptr () {p = new map <int, int> (); for (int I = 0; I <MAXN; I ++) p-> insert (make_pair (I, I ));}~ Test_ptr () {delete p ;}}; int main (int argc, char * argv []) {for (int I = 0; I <100; I ++) {Sleep (1000); cout <I <endl; // output the number of times createdAuto_ptr <test_ptr> tmp = auto_ptr <test_ptr> (new test_ptr ());} System ("pause"); return 0 ;}
In the main function, when a pointer of the test_ptr type is created, the pointer is a smart pointer of the auto_ptr type. When the smart pointer fails, the destructor of this class is automatically called. Therefore, this statement can no longer display the call to the delete statement. However, this smart pointer only ensures that the class's destructor are called. What should we do if the Destructor does not release the variables declared in the class.
Code snippet 4:
# Include <iostream> # include <string. h> # include <memory> # include <string> # include <Windows. h >#include <map> # include <ctime> # include <vector> using namespace std; # define MAXN 20000000 class test_ptr {public: // auto_ptr <map <int, int> p; map <int, int> * p; test_ptr () {// p = auto_ptr <map <int, int> (new map <int, int> (); p = new map <int, int> (); for (int I = 0; I <MAXN; I ++) p-> insert (make_pair (I, I ));}/*~ Test_ptr () {delete p;} */}; int main (int argc, char * argv []) {for (int I = 0; I <100; I ++) {Sleep (1000); cout <I <endl; // number of times auto_ptr <test_ptr> tmp = auto_ptr <test_ptr> (new test_ptr ());} system ("pause"); return 0 ;}
In this case, memory leakage still occurs. To solve this problem, the pointer declared in the class also needs to be declared as auto_ptr type.
Code snippet 5:
# Include <iostream> # include <string. h> # include <memory> # include <string> # include <Windows. h >#include <map> # include <ctime> # include <vector> using namespace std; # define MAXN 20000000 class test_ptr {public: auto_ptr <map <int, int> p; test_ptr () {p = auto_ptr <map <int, int> (new map <int, int> (); for (int I = 0; I <MAXN; I ++) p-> insert (make_pair (I, I) ;}}; int main (int argc, char * argv []) {for (int I = 0; I <100; I ++) {Sleep (1000); cout <I <endl; // output auto_ptr <test_ptr> tmp = auto_ptr <test_ptr> (new test_ptr () ;}system ("pause"); return 0 ;}
In this way, you do not need to display the destructor of the definition class, or call the delete function externally. Of course, you can call the delete function as soon as possible, releasing the memory as soon as possible is better than failing the pointer and then releasing it. This is to prevent the call from being forgotten.
Through the above analysis: the following conclusions can be drawn.
1. A smart pointer is defined. When the smart pointer fails, the class destructor are automatically called.
2. The smart pointer defined in the class does not need to display the delete statement in the destructor. When the destructor of the class is called externally, the object pointed to by the smart pointer is automatically released, release memory.
3. If the class is defined as a smart pointer, but the class's destructor call is not triggered externally, the object to which the smart pointer points cannot be released.
Auto_ptr smart pointer bug
Auto_ptr smart pointers have been discarded in the c ++ 11 standard because of this bug. As mentioned above, an object can only be referenced by one smart pointer, which leads to a problem of value assignment. See the following code:
Code snippet 6:
1 #include <iostream> 2 3 #include <string.h> 4 #include <memory> 5 #include <set> 6 7 using namespace std; 8 9 10 #define MAXN 2000000011 12 void pri(auto_ptr<set<int> > p)13 {14 set<int>::iterator ite = p->begin();15 for(;ite!=p->end();ite++)16 {17 cout << *ite << endl;18 }19 }20 21 int main(int argc,char *argv[])22 {23 auto_ptr<set<int> > ptr(new set<int> ());24 25 for(int i = 0;i< 3;i++)26 {27 int a;28 cin >> a;29 ptr->insert(a);30 }31 32 pri(ptr);33 34 pri(ptr);35 36 system("pause");37 return 0;38 }
At first glance, there is no problem with this code, but the running program will crash. This is the biggest bug of the smart pointer. When the program calls pri (ptr) in Row 32, the program does not solve this problem, but the program crashes when the pri (ptr) is called for the second time. The reason is that, as mentioned above, an object intelligence is pointed to by a smart pointer. when calling the pri () function for the first time, to ensure this principle, when the ptr pointer is passed into the pri function, the ptr is set to null in the program, so the second call will crash. The solution to this problem is to use the shared_ptr pointer (this pointer is implemented by referencing the counter ).
To use the shared_ptr smart pointer, you need to install the boost library, which also includes many other features. If you are interested, try the following. The smart pointer in this class is better. There are no many other bugs.
I will introduce shared_ptr pointer in the boost library in detail if I have time