静态内存用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量。栈内存用来保存定义在函数内的非static对象。分配在静态或栈内存中的对象由编译器自动创建和销毁。对于栈对象,仅在其定义的程序块运行时才存在;static对象在使用之前分配,在程序结束时销毁。
除了静态内存和栈内存,每个程序还拥有一个内存池。这部分内存被称作自由空间或堆。程序用堆来存储动态分配的对象——即,那些在程序运行时分配的对象。动态对象的生存期由程序来控制,也就是说,当动态对象不再使用时,我们的代码必须显示地销毁它们。
new:在动态内存中为对象分配空间并返回一个指向对象的指针,我们可以选择对对象进行初始化;delete,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。新的标准库提供了两种智能指针类型来管理动态对象。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。新标准提供的这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个指针指向同一个对象;unique_ptr则“独占”所指向的对象。
接受智能指针参数的智能指针构造函数时explicit的。因此,我们不能将一个内置指针隐式转换为一个智能指针,必须使用直接初始化来初始化一个智能指针:
智能指针可以提供对动态分配的内存安全而又方便的管理,但这建立在正确使用的前提下。为了正确使用智能指针,我们必须坚持一些基本的规范:
1.不使用相同的内置指针值初始化(或reset)多个智能指针。
2.不delete get()返回的指针
3.不使用get()初始化或reset另一个智能指针
4.如果你使用get()返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了。
5.如果你使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器。
int *p = new int[42];
当用new分配一个数组时,我们并未得到一个数组类型的对象,而是得到一个数组元素类型的指针。由于分配的内存并不是一个数组类型,因此不能对动态数组调用begin或end。出于相同的原因,也不能用范围for语句来处理动态数组中的元素。
delete []p;数组的元素按逆序销毁,即,最后一个元素首先被销毁,然后是倒数第二个,依次类推。