总结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. 拷贝构造函数导致重复释放
- #include <string.h>
- #include <iostream>
- using namespace std;
- class MyString
- {
- private:
- int length;
- char* value;
- public:
- MyString(const char* str = NULL){
- length = 0;
- value = NULL;
- SetString(str);
- }
- ~MyString(){
- delete[] value;
- }
- public:
- void SetString(const char* str){
- if(str != NULL){
- length = strlen(str);
- value = new char[length + 1];
- memcpy(value, str, length);
- value[length] = 0x00;
- }
- }
- public:
- const char* GetString(){
- return (const char*)value;
- }
- };
- int main(){
- MyString str("winlin");
- str = "hello world";
- cout << "expect: hello world, actual: " << str.GetString() << endl;
- sleep(5);
- return 0;
- }
#include <string.h>#include <iostream>using namespace std;class MyString{private: int length; char* value;public: MyString(const char* str = NULL){ length = 0; value = NULL; SetString(str); } ~MyString(){ delete[] value; }public: void SetString(const char* str){ if(str != NULL){ length = strlen(str); value = new char[length + 1]; memcpy(value, str, length); value[length] = 0x00; } }public: const char* GetString(){ return (const char*)value; }};int main(){ MyString str("winlin"); str = "hello world"; cout << "expect: hello world, actual: " << str.GetString() << endl; sleep(5); return 0;}
2. 内存越界导致错误
- /**
- # build the gperftools:
- bash build_gperftools.memory-fence.sh
- # to build:
- 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
- */
- #include <stdio.h>
- class Connection;
- class State
- {
- private:
- Connection* conn;
- public:
- State(Connection* c) : conn(c){
- }
- virtual ~State(){
- }
- void action();
- };
- class Manager;
- class Connection
- {
- private:
- State* state;
- Manager* manager;
- public:
- Connection(){
- state = NULL;
- }
- virtual ~Connection(){
- if(state != NULL){
- delete state;
- state = NULL;
- }
- }
- public:
- void SetManager(Manager* m){
- manager = m;
- }
- Manager* GetManager(){
- return manager;
- }
- void SetState(State* s){
- state = s;
- }
- };
- class Manager
- {
- private:
- Connection* conn;
- public:
- Manager(){
- conn = NULL;
- }
- virtual ~Manager(){
- }
- public:
- void Destroy(){
- if(conn != NULL){
- delete conn;
- conn = NULL;
- }
- }
- Connection* GetConnection(){
- return conn;
- }
- void SetConnection(Connection* c){
- conn = c;
- conn->SetManager(this);
- }
- };
- void State::action(){
- if(conn == NULL){
- return;
- }
- conn->GetManager()->Destroy();
- this->conn = NULL;
- }
- int main(int /*argc*/, char** /*argv*/){
- Manager manager;
- Connection* connection = new Connection();
- State* state = new State(connection);
- connection->SetState(state);
- manager.SetConnection(connection);
- state->action();
- return 0;
- }
/**# build the gperftools:bash build_gperftools.memory-fence.sh# to build: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*/#include <stdio.h>class Connection;class State{private: Connection* conn;public: State(Connection* c) : conn(c){ } virtual ~State(){ } void action();};class Manager;class Connection{private: State* state; Manager* manager;public: Connection(){ state = NULL; } virtual ~Connection(){ if(state != NULL){ delete state; state = NULL; } }public: void SetManager(Manager* m){ manager = m; } Manager* GetManager(){ return manager; } void SetState(State* s){ state = s; }};class Manager{private: Connection* conn;public: Manager(){ conn = NULL; } virtual ~Manager(){ }public: void Destroy(){ if(conn != NULL){ delete conn; conn = NULL; } } Connection* GetConnection(){ return conn; } void SetConnection(Connection* c){ conn = c; conn->SetManager(this); }};void State::action(){ if(conn == NULL){ return; } conn->GetManager()->Destroy(); this->conn = NULL;}int main(int /*argc*/, char** /*argv*/){ Manager manager; Connection* connection = new Connection(); State* state = new State(connection); connection->SetState(state); manager.SetConnection(connection); state->action(); return 0;}
3. 非虚析构函数导致内存泄漏
- /**
- g++ -g -O0 use-interface.cpp -o use-interface; ./use-interface
- */
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- class IObject
- {
- public:
- virtual const char* ToString() = 0;
- };
- class String : public IObject
- {
- private:
- char* str;
- public:
- String(const char* s){
- str = NULL;
- if(s != NULL){
- str = new char[strlen(s) + 1];
- strcpy(str, s);
- }
- }
- virtual ~String(){
- if(str != NULL){
- delete[] str;
- }
- }
- public:
- virtual const char* ToString(){
- return str;
- }
- };
- void destroy(IObject* obj){
- delete obj;
- }
- int main(int /*argc*/, char** /*argv*/){
- while(true){
- destroy(new String("winlin"));
- usleep(1);
- }
- return 0;
- }
/**g++ -g -O0 use-interface.cpp -o use-interface; ./use-interface*/#include <stdio.h>#include <string.h>#include <unistd.h>class IObject{public: virtual const char* ToString() = 0;};class String : public IObject{private: char* str;public: String(const char* s){ str = NULL; if(s != NULL){ str = new char[strlen(s) + 1]; strcpy(str, s); } } virtual ~String(){ if(str != NULL){ delete[] str; } }public: virtual const char* ToString(){ return str; }};void destroy(IObject* obj){ delete obj;}int main(int /*argc*/, char** /*argv*/){ while(true){ destroy(new String("winlin")); usleep(1); } return 0;}
4. 局部数组越界导致栈错误
- /**
- g++ -g -O0 stack-corrupt.cpp -o stack-corrupt; ./stack-corrupt
- */
- #include <stdio.h>
- #include <string.h>
- void packet_unmarshal(char* stream, int size){
- printf("memcpy, size=%d\n", size);
- // decode packet from stream.
- char data[100];
- memcpy(data, stream, size);
- printf("memcpy finished\n");
- }
- void normal_opration3(){
- char stream[116];
- packet_unmarshal(stream, sizeof(stream));
- printf("normal opration3\n");
- }
- void normal_opration2(){
- normal_opration3();
- printf("normal opration2\n");
- }
- void normal_opration1(){
- normal_opration2();
- printf("normal opration1\n");
- }
- void normal_opration(){
- normal_opration1();
- printf("normal opration\n");
- }
- int main(int /*argc*/, char** /*argv*/){
- normal_opration();
- return 0;
- }
- 总结c++内存错误的典型情况
- 总结c++内存错误的典型情况 .
- C语言常见的内存错误总结
- 【读书笔记】C程序中常见的内存操作有关的典型编程错误
- C关于typedef的两个典型错误!
- C 关于sizeof的典型错误
- mybatis典型错误总结
- C典型错误
- 可能发送内存段错误的情况
- sql2005常见典型错误总结
- sql2005常见典型错误总结
- 一个C语言典型的内存泄露问题
- 典型的逻辑错误!
- 典型的段错误
- opencv各种内存泄露情况的总结
- C语言系统内存被踩情况总结
- 开发艺术探索阅读总结(1.1)典型情况下的生命周期的分析
- ISIS的典型配置和路由情况
- js 放在html 的位置 不同 造成的结果页不相同
- Spring mvc中@RequestMapping 6个基本用法小结
- 2013,这一年
- Redis 入门实践
- C#中用ILMerge将所有引用的DLL和exe文件打成一个exe文件
- 总结c++内存错误的典型情况 .
- js中两个感叹号的原理与用法分析
- SpringMVC表单标签简介
- mysql 字段值默认不区分大小写
- JAVA字符串的反转和比较
- jquery表格插件Flexigrid前台 后台 及改变其url等属性
- 在Eclipse中导入android sdk源码
- Android Asset Studio
- 第一辑 回家的路--幸福参照系