非正确经验引发C++内存泄露
来源:互联网 发布:淘宝宽屏海报代码 编辑:程序博客网 时间:2024/06/05 17:02
http://blog.csdn.net/lincyang/article/details/8656456
眼见的事实尚有假,背后的言语未必真。---谚语
当使用另一种方式去实现相同的任务时,过往的经验可以帮助你更快速的分析和实现。但有时候经验也会产生负面影响。
下面的一段例子表示当一个对象以值的形式包含另一个对象时,会自动调用另一个对象的析构函数。
- #include <iostream>
- #include <cstring>
- using namespace std;
- class Tyre
- {
- char* brand;
- public:
- Tyre(Tyre &tyre)
- {
- cout<<"first construct."<<endl;
- this->brand = new char[strlen(tyre.brand)+1];
- strcpy(this->brand,tyre.brand);
- }
- Tyre(char* _brand)
- {
- cout<<"Tyre("<<_brand<<")"<<endl;
- this->brand = new char[strlen(_brand)+1];
- strcpy(this->brand,_brand);
- }
- ~Tyre()
- {
- cout<<"Tyre destruct:"<<brand<<endl;
- delete brand;
- }
- void print()
- {
- cout<<"This is "<<brand<<" Tyre."<<endl;
- }
- };
-
-
- class Car
- {
- char* name;
- Tyre tyre2;
- public:
- Car(char* name,Tyre tyre):tyre2(tyre)
- {
- this->name = new char[strlen(name)+1];
- strcpy(this->name,name);
- tyre2.print();
- }
- ~Car()
- {
- cout<<"Car destructor:only delete name"<<endl;
- delete name;
- }
- void print()
- {
- cout<<"Car :";
- this->tyre2.print();
- }
- };
-
- int main()
- {
-
- Tyre tyre1("g");
- Car theCar("lexus",tyre1);
- theCar.print();
-
- return 0;
- }
编译:gcc -o leak main2.cpp -lstdc++运行:- D:\workspace\C++\memory_leak\leak2>leak
- Tyre(g)
- first construct.
- first construct.
- This is g Tyre.
- Tyre destruct:g
- Car :This is g Tyre.
- Car destructor:only delete name
- Tyre destruct:g
- Tyre destruct:g
以引用的方式也一样自动调用其析构:
-
- #include <iostream>
- #include <cstring>
- using namespace std;
- class Tyre
- {
- char* brand;
- public:
- Tyre(char* _brand);
- ~Tyre();
- void print();
- };
-
- Tyre::Tyre(char* _brand)
- {
- cout<<"Tyre("<<_brand<<")"<<endl;
- this->brand = new char[strlen(_brand)+1];
- strcpy(this->brand,_brand);
- }
-
- Tyre::~Tyre()
- {
- cout<<"Tyre destruct:"<<brand<<endl;
- delete brand;
- }
-
- void Tyre::print()
- {
- cout<<"This is "<<brand<<" Tyre."<<endl;
- }
-
- class Car
- {
- char* name;
- Tyre& tyre2;
- public:
- Car(char* name,Tyre& tyre);
- ~Car();
- void print();
- };
-
- Car::Car(char* name,Tyre& tyre):tyre2(tyre)
- {
- this->name = new char[strlen(name)+1];
- strcpy(this->name,name);
- tyre2.print();
- }
-
- Car::~Car()
- {
- cout<<"Car destructor:only delete name"<<endl;
- delete name;
- }
-
- void Car::print()
- {
- cout<<"Car :";
- this->tyre2.print();
- }
-
- int main()
- {
-
- Tyre tyre1("g");
- Car theCar("lexus",tyre1);
- theCar.print();
-
- return 0;
- }
编译运行结果:- D:\workspace\C++\memory_leak\leak2>leak
- Tyre(g)
- This is g Tyre.
- Car :This is g Tyre.
- Car destructor:only delete name
- Tyre destruct:g
而当包含对象的指针时,就不会像之前那样自动调用析构了,必须要像以前的规则,new和delete要成对出现:-
- #include <iostream>
- #include <cstring>
- using namespace std;
- class Tyre
- {
- char* brand;
- public:
- Tyre(char* _brand);
- ~Tyre();
- void print();
- };
-
- Tyre::Tyre(char* _brand)
- {
- cout<<"Tyre("<<_brand<<")"<<endl;
- this->brand = new char[strlen(_brand)+1];
- strcpy(this->brand,_brand);
- }
-
- Tyre::~Tyre()
- {
- cout<<"Tyre destruct:"<<brand<<endl;
- delete brand;
- }
-
- void Tyre::print()
- {
- cout<<"This is "<<brand<<" Tyre."<<endl;
- }
-
- class Car
- {
- char* name;
- Tyre* tyre;
- public:
- Car(char* name,char* _tyre);
- ~Car();
- void print();
- };
-
- Car::Car(char* name,char* _tyre)
- {
- this->name = new char[strlen(name)+1];
- strcpy(this->name,name);
- tyre = new Tyre(_tyre);
- }
-
- Car::~Car()
- {
- cout<<"Car destructor:only delete name"<<endl;
- delete name;
-
- }
-
- void Car::print()
- {
- cout<<"Car :";
- tyre->print();
- }
-
- int main()
- {
- Car car1("benz","goodyear");
- car1.print();
- Car car2("bmw","michelin");
- car2.print();
-
- Car *car3 = new Car("audi","continental");
- car3->print();
- delete car3;
-
- return 0;
- }
运行结果如下:- D:\workspace\C++\memory_leak\leak2>leak
- Tyre(goodyear)
- Car :This is goodyear Tyre.
- Tyre(michelin)
- Car :This is michelin Tyre.
- Tyre(continental)
- Car :This is continental Tyre.
- Car destructor:only delete name
- Car destructor:only delete name
- Car destructor:only delete name
有三个Tyre没有释放内存,Car::~Car中解开注释,编译运行如下:- D:\workspace\C++\memory_leak\leak2>leak
- Tyre(goodyear)
- Car :This is goodyear Tyre.
- Tyre(michelin)
- Car :This is michelin Tyre.
- Tyre(continental)
- Car :This is continental Tyre.
- Car destructor:only delete name
- Tyre destruct:continental
- Car destructor:only delete name
- Tyre destruct:michelin
- Car destructor:only delete name
- Tyre destruct:goodyear
生活中不能缺少经验,但不要迷信经验。