一:直接内存管理(new / delete)
new分配方式称之为动态分配,分配在堆上,直接内存管理
myfun();
A a; // 编译器帮助我们创建a对象
14.4.2 讲过 堆 栈 概念
14.6.4 new delete 对象
new分配方式我们称为动态分配(分配在堆上) :直接内存管理(new/delete);
如何初始化:
int main()
{
int* pointi_1 = new int;
int* pointi_2 = new int(); //初值未定义
int* point2 = new int(100); //用圆括号给一个int的动态对象初值
string* string1 = new string(5, 'a'); //生成一个字符串,字符串内容是5个'a'
vector<int>* pointv = new vector<int>{ 1,2,3,4,5 }; //一个容器对象,里面有5个元素。
return 0;
}
概念“值初始化”:用()来初始化
string* str = new string(); //也是空字符串, 和mystr没啥区别
int* po int3 = new int(); //值初始化的方式,发现point3的值被初始化为0;
A* pa = new A;
A* pa2 = new A(); //是否是"值初始化"效果一样,都是调用A的构造函数
new对象的时候,能够进行"值初始化"就进行一下为好,防止它的值没有被初始化
C++11中,auto可以和new配合使用
int main()
{
string* string1 = new string(5, 'a');
auto string2 = new auto(string1); //string3 = string **
string** string3 = new string * (string1); //string3 = string **
cout << string1->c_str() << endl;
//cout << string2->c_str() << endl; //报错
cout << (*string3)->c_str() << endl;
return 0;
}
delete string1;
delete string3; //指针的指针,销毁方法不一样,结果不一样
delete string3;
cout << string1->c_str() << endl;
delete string1; //指针的指针,销毁方法不一样,结果不一样
const 对象也可以动态分配
const int* pointci = new const int(200);
new和delete说明:
<1>成对使用,delete 是回收用 new 分配的内存(释放内存),不是 new 出来的内存,是不能用 delete 释放。
<2>delete 一块内存,只能 delete 一次,不能 delete 多次。delete 后,这块内存就不能使用。
空指针可以删除多次,但删除多次没有什么意义。
int main()
{
char* p_c = nullptr;
delete p_c;
//delete p_c;
int i = 12;
int* p_i_1 = &i;
//delete p_i_1; //*不是new出来的对象不能delete,否则执行会报告异常
int* p_i_2 = new int();
int* p_i_3 = p_i_2;
delete p_i_3; //没问题
//delete p_i_2; //异常,因为p和p2都指向同一段内存;
return 0;
}
注意事项总结:
<1>new 出来的千万不要忘记 delete,否则内存泄漏,时间一长导致系统资源紧张,运行崩溃;
<2>delete 后的内存不能再使用,否则异常。
int main()
{
int* pci = new int(300);
*pci = 500;
delete pci;
//*pci = 600;
pci = nullptr; //这是个好习惯,表明该指针不指向任何对象了;老师提倡delete一个指针后,给该指针一个nulllptr。
return 0;
}
<3>同一块内存释放两次的问题;也会报异常
用 new 和 delete 直接进行内存管理,要很小心;
C++11 开始出现"智能指针" new,忘记了 delete,智能指针能够帮助你 delete。
二:创建新工程与观察内存泄漏
MFC应用程序能够在一定的程度上(程序退出的时候),能够帮助我们发现内存泄漏。