在析构函数与构造函数中使用动态内存
1.析构函数的使用
(1)析构函数在对象对销毁时自动调用,一般有2种情况 (2)用new分配的对象,用delete显式析构 (3)分配在栈上的对象,当栈释放时自动析构 (4)普通情况下析构函数都是空的,因为不必做什么特别的事情
2.在class中使用动态内存变量
(1)什么情况下用动态内存? 需要大块内存,且需要按需灵活的申请和释放,用栈怕爆、用全局怕浪费和死板时 (2)在class person中增加一个int *指针,用于指向一个int类型元素的内存空间 (3)在构造函数中分配动态内存 (4)在析构函数中回收动态内存 (5)将动态内存从int变量升级到int数组变量 (6)实战中C++常用的动态内存往往是容器vector那些
3.用valgrind工具查看内存泄漏
实际开发中,程序较复杂时,可能会出现内存泄漏,可以使用工具检测
(1)valgrind工具介绍:参考:https://blog.csdn.net/u012662731/article/details/78652651 (2)安装:sudo apt-get install valgrind(ubuntu16.04 X64) (3)编译程序:主要是添加-g参数便于调试时有行号 g++ person.cpp main.cpp -g -o apptest (4)使用:valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./app
1 #include "person.hpp" 2 3 using namespace MAN; 4 5 6 int main(void) 7 { 8 // 人的一天的生活 9 string s1 = "linux"; 10 person pPerson(s1); // 创建了一个person的对象,分配在栈上 11 // person lisi; 12 13 // pPerson->name = "zhangsan"; 14 pPerson.age = 23; 15 pPerson.male = 1; 16 // pPerson->p = malloc(256); 17 18 pPerson.eat(); 19 pPerson.work(); 20 pPerson.eat(); 21 pPerson.work(); 22 pPerson.sleep(); 23 24 // 用完对象后就销毁它 25 // delete pPerson; 26 27 28 #if 0 29 // 人的一天的生活 30 string s1 = "linux"; 31 person* pPerson = new person(s1); // 创建了一个person的对象,分配在堆上 32 // person lisi; 33 34 // pPerson->name = "zhangsan"; 35 pPerson->age = 23; 36 pPerson->male = 1; 37 // pPerson->p = malloc(256); 38 39 pPerson->eat(); 40 pPerson->work(); 41 pPerson->eat(); 42 pPerson->work(); 43 pPerson->sleep(); 44 45 // 用完对象后就销毁它 46 delete pPerson; 47 #endif 48 49 50 return 0; 51 }
1 #ifndef __PERSON_H__ 2 #define __PERSON_H__ 3 4 5 #include <string> 6 using namespace std; 7 8 namespace MAN 9 { 10 11 12 // 声明这个类 13 class person 14 { 15 // 访问权限 16 public: 17 // 属性 18 string name; // 名字 19 int age; // 年龄 20 bool male; // 性别,男为true,女为false 21 int* pInt; // 只是分配了p本身的4字节内存,并没有分配p指向的空间内存 22 23 // 构造和析构 24 person(); // 默认构造函数 25 person(string name); // 自定义构造函数 26 27 ~person(); // 默认析构函数 28 29 // 方法 30 void eat(void); 31 void work(void); 32 void sleep(void); 33 34 35 private: 36 37 }; 38 39 } // end of namespace MAN 40 41 42 43 #endif 44 45 #pragma once
1 #include "person.hpp" 2 #include <iostream> 3 4 using namespace std; 5 6 7 // class的成员函数中可以引用class的成员变量,但是要考虑public和private这些 8 void MAN::person::eat(void) 9 { 10 cout << name << " eat" << endl; 11 } 12 13 void MAN::person::work(void) 14 { 15 // cout << "person work" << endl; 16 if (this->male) 17 { 18 cout << this->name << " coding" << endl; 19 } 20 else 21 { 22 cout << this->name << " shopping" << endl; 23 } 24 } 25 26 27 void MAN::person::sleep(void) 28 { 29 // cout << "value of this->pInt = " << *(this->pInt) << endl; 30 for (int i = 0; i < 10; i++) 31 { 32 this->pInt[i] = i; 33 } 34 35 for (int i = 0; i < 10; i++) 36 { 37 cout << "pInt[" << i << "] = " << pInt[i] << endl; 38 } 39 40 cout << this->name << " sleep" << endl; 41 } 42 43 44 MAN::person::person() 45 { 46 // 默认构造函数是空的 47 cout << "default constructor" << endl; 48 } 49 50 MAN::person::person(string name) 51 { 52 // 默认构造函数是空的 53 this->name = name; // 构造对象后,同时对对象中的name属性进行初始化 54 55 // 在构造函数中对class中需要分配动态内存的指针进行动态分配 56 // this->pInt = new int(55); 57 this->pInt = new int[10]; // 分配了100个元素的数组 58 59 cout << "userdefined constructor" << endl; 60 } 61 62 63 MAN::person::~person() 64 { 65 // 默认析构函数是空的 66 // delete this->pInt; // 释放单个内存 67 delete[] this->pInt; // 释放数组内存 68 69 cout << "userdefined destructor" << endl; 70 }