总结c++内存错误的典型情况 .

来源:互联网 发布:ubuntu 14.04 uefi 编辑:程序博客网 时间:2024/05/17 01:22

最近遇到了c++几张内存错误的几种典型情况:

1. 拷贝构造函数导致重复释放:http://blog.csdn.net/winlinvip/article/details/7663862

2. 内存越界导致错误:这个在http://blog.csdn.net/winlinvip/article/details/7822762 提到过。

3. 非虚析构函数导致内存泄漏:http://blog.csdn.net/winlinvip/article/details/7667460

4. 局部数组越界导致栈错误:http://blog.csdn.net/winlinvip/article/details/7822762 稍微提了一下。


把重现它们的代码集中放到这里:

1. 拷贝构造函数导致重复释放

[cpp] view plaincopyprint?
  1. #include <string.h>   
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. class MyString  
  6. {  
  7. private:  
  8.     int length;  
  9.     char* value;  
  10. public:  
  11.     MyString(const char* str = NULL){  
  12.         length = 0;  
  13.         value = NULL;  
  14.         SetString(str);  
  15.     }  
  16.     ~MyString(){  
  17.         delete[] value;  
  18.     }  
  19. public:  
  20.     void SetString(const char* str){  
  21.         if(str != NULL){  
  22.             length = strlen(str);  
  23.             value = new char[length + 1];  
  24.             memcpy(value, str, length);  
  25.             value[length] = 0x00;  
  26.         }  
  27.     }  
  28. public:  
  29.     const char* GetString(){  
  30.         return (const char*)value;  
  31.     }  
  32. };  
  33.   
  34. int main(){  
  35.     MyString str("winlin");  
  36.     str = "hello world";  
  37.     cout << "expect: hello world, actual: " << str.GetString() << endl;  
  38.     sleep(5);  
  39.     return 0;  
  40. }  


2. 内存越界导致错误

[cpp] view plaincopyprint?
  1. /** 
  2. # build the gperftools: 
  3. bash build_gperftools.memory-fence.sh 
  4. # to build: 
  5. g++ -g -O0 -c memcorrupt.cpp -o memcorrupt.o -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free; g++ memcorrupt.o -o memcorrupt -ltcmalloc_debug; ./memcorrupt 
  6. */  
  7. #include <stdio.h>   
  8.   
  9. class Connection;  
  10. class State  
  11. {  
  12. private:  
  13.     Connection* conn;  
  14. public:  
  15.     State(Connection* c) : conn(c){  
  16.     }  
  17.     virtual ~State(){  
  18.     }  
  19.     void action();  
  20. };  
  21.   
  22. class Manager;  
  23. class Connection  
  24. {  
  25. private:  
  26.     State* state;  
  27.     Manager* manager;  
  28. public:  
  29.     Connection(){  
  30.         state = NULL;  
  31.     }  
  32.     virtual ~Connection(){  
  33.         if(state != NULL){  
  34.             delete state;  
  35.             state = NULL;  
  36.         }  
  37.     }  
  38. public:  
  39.     void SetManager(Manager* m){  
  40.         manager = m;  
  41.     }  
  42.     Manager* GetManager(){  
  43.         return manager;  
  44.     }  
  45.     void SetState(State* s){  
  46.         state = s;  
  47.     }  
  48. };  
  49.   
  50. class Manager  
  51. {  
  52. private:  
  53.     Connection* conn;  
  54. public:  
  55.     Manager(){  
  56.         conn = NULL;  
  57.     }  
  58.     virtual ~Manager(){  
  59.     }  
  60. public:  
  61.     void Destroy(){  
  62.         if(conn != NULL){  
  63.             delete conn;  
  64.             conn = NULL;  
  65.         }  
  66.     }  
  67.     Connection* GetConnection(){  
  68.         return conn;  
  69.     }  
  70.     void SetConnection(Connection* c){  
  71.         conn = c;  
  72.         conn->SetManager(this);  
  73.     }  
  74. };  
  75.   
  76. void State::action(){  
  77.     if(conn == NULL){  
  78.         return;  
  79.     }  
  80.       
  81.     conn->GetManager()->Destroy();  
  82.     this->conn = NULL;  
  83. }  
  84.   
  85. int main(int /*argc*/char** /*argv*/){  
  86.     Manager manager;  
  87.     Connection* connection = new Connection();  
  88.     State* state = new State(connection);  
  89.       
  90.     connection->SetState(state);  
  91.     manager.SetConnection(connection);  
  92.       
  93.     state->action();  
  94.       
  95.     return 0;  
  96. }  


3. 非虚析构函数导致内存泄漏

[cpp] view plaincopyprint?
  1. /** 
  2. g++ -g -O0 use-interface.cpp -o use-interface; ./use-interface 
  3. */  
  4. #include <stdio.h>   
  5. #include <string.h>   
  6. #include <unistd.h>   
  7.   
  8. class IObject  
  9. {  
  10. public:  
  11.     virtual const char* ToString() = 0;  
  12. };  
  13.   
  14. class String : public IObject  
  15. {  
  16. private:  
  17.     char* str;  
  18. public:  
  19.     String(const char* s){  
  20.         str = NULL;  
  21.         if(s != NULL){  
  22.             str = new char[strlen(s) + 1];  
  23.             strcpy(str, s);  
  24.         }  
  25.     }  
  26.     virtual ~String(){  
  27.         if(str != NULL){  
  28.             delete[] str;  
  29.         }  
  30.     }  
  31. public:  
  32.     virtual const char* ToString(){  
  33.         return str;  
  34.     }  
  35. };  
  36.   
  37. void destroy(IObject* obj){  
  38.     delete obj;  
  39. }  
  40.   
  41. int main(int /*argc*/char** /*argv*/){  
  42.     while(true){  
  43.         destroy(new String("winlin"));  
  44.         usleep(1);  
  45.     }  
  46.     return 0;  
  47. }  


4. 局部数组越界导致栈错误

[cpp] view plaincopyprint?
  1. /** 
  2. g++ -g -O0 stack-corrupt.cpp -o stack-corrupt; ./stack-corrupt 
  3. */  
  4. #include <stdio.h>   
  5. #include <string.h>   
  6.   
  7. void packet_unmarshal(char* stream, int size){  
  8.     printf("memcpy, size=%d\n", size);  
  9.       
  10.     // decode packet from stream.   
  11.     char data[100];  
  12.     memcpy(data, stream, size);  
  13.       
  14.     printf("memcpy finished\n");  
  15. }  
  16.   
  17. void normal_opration3(){  
  18.     char stream[116];  
  19.     packet_unmarshal(stream, sizeof(stream));  
  20.     printf("normal opration3\n");  
  21. }  
  22. void normal_opration2(){  
  23.     normal_opration3();  
  24.     printf("normal opration2\n");  
  25. }  
  26. void normal_opration1(){  
  27.     normal_opration2();  
  28.     printf("normal opration1\n");  
  29. }  
  30. void normal_opration(){  
  31.     normal_opration1();  
  32.     printf("normal opration\n");  
  33. }  
  34.   
  35. int main(int /*argc*/char** /*argv*/){  
  36.     normal_opration();  
  37.     return 0;  
  38. }  
原创粉丝点击