9.2.10 存储方案和动态分配(1)
前面介绍C++(www.cppentry.com)用来为变量(包括数组和结构)分配内存的5种方案(线程内存除外),它们不适用于使用C++(www.cppentry.com)运算符new(或C函数malloc( ))分配的内存,这种内存被称为动态内存。第4章介绍过,动态内存由运算符new和delete控制,而不是由作用域和链接性规则控制。因此,可以在一个函数中分配动态内存,而在另一个函数中将其释放。与自动内存不同,动态内存不是LIFO,其分配和释放顺序要取决于new和delete在何时以何种方式被使用。通常,编译器使用三块独立的内存:一块用于静态变量(可能再细分),一块用于自动变量,另外一块用于动态存储。
虽然存储方案概念不适用于动态内存,但适用于用来跟踪动态内存的自动和静态指针变量。例如,假设在一个函数中包含下面的语句:
由new分配的80个字节(假设float为4个字节)的内存将一直保留在内存中,直到使用delete运算符将其释放。但当包含该声明的语句块执行完毕时,p_fees指针将消失。如果希望另一个函数能够使用这80个字节中的内容,则必须将其地址传递或返回给该函数。另一方面,如果将p_fees的链接性声明为外部的,则文件中位于该声明后面的所有函数都可以使用它。另外,通过在另一个文件中使用下述声明,便可在其中使用该指针:
注意:在程序结束时,由new分配的内存通常都将被释放,不过情况也并不总是这样。例如,在不那么健壮的操作系统中,在某些情况下,请求大型内存块将导致该代码块在程序结束不会被自动释放。最佳的做法是,使用delete来释放new分配的内存。
1.使用new运算符初始化
如果要初始化动态分配的变量,该如何办呢?在C++(www.cppentry.com)98中,有时候可以这样做,C++(www.cppentry.com)11增加了其他可能性。下面先来看看C++(www.cppentry.com)98提供的可能性。
如果要为内置的标量类型(如int或double)分配存储空间并初始化,可在类型名后面加上初始值,并将其用括号括起:
这种括号语法也可用于有合适构造函数的类,这将在本书后面介绍。
然而,要初始化常规结构或数组,需要使用大括号的列表初始化,这要求编译器支持C++(www.cppentry.com)11。C++(www.cppentry.com)11允许您这样做:
在C++(www.cppentry.com)11中,还可将列表初始化用于单值变量:
2.new失败时
new可能找不到请求的内存量。在最初的10年中,C++(www.cppentry.com)在这种情况下让new返回空指针,但现在将引发异常std::bad_alloc。第15章通过一些简单的示例演示了这两种方法的工作原理。