- 定义:
C++中,动态内存分配技术可以保证程序在运行过程中按照实际需要申请适量的内存,使用结束后还可以释放
这种在程序运行过程中,申请和释放的存储单元称为
堆对象,申请和释放过程一般称为建立和删除
C++建立和删除堆对象使用两个运算符:new 和 delete
运算符:new
功能:动态分配内存,或者动态创建堆对象
语法形式:
new 数据类型(初始化参数列表);
内存申请成功,new运算返回一个指向新分配内存首地址的类型的指针(可以通过这个指针访问堆对象);申请失败,抛出异常
eg:
int * point = new int; 无括号,不初始化
int * point = new int(); 有括号,无初始值,表示用0对其初始化
new 建立类的对象:
1) 当有默认构造函数
new 类名 与 new 类名() 等效,都会调用默认构造函数
2) 当未定义默认构造函数:
new 类名 会调用隐含默认构造函数
new 类名():系统除了执行默认构造函数,还会为基本数据类型和指针类型的成员用0赋初值(这一过程是递归的)
运算符: delete
语法形式: delete 指针名;
功能:用于删除new建立的对象,释放指针所指向的内存空间
如果被删除的是对象,该对象的析构函数将被调用
对于用new分配的内存,只能使用delete进行一次删除操作,如果对同一内存空间使用多次delete进行删除会导致运行错误
注意: 用new分配的内存,必须用delete加以释放,否则会导致
内存泄露:动态内存分配的内存无法回收,使得程序占据的内存越来越大
2. new 运算符动态创建
数组:
- 一维数组
语法形式:
new 类型名[数组长度]; 数组长度指出了数组元素的个数 ,可以是任何正整数值的表达式
细节: new 类型名[数组长度]: 无括号,则与执行 "new T" 进行的初始化方式一样 [
无括号,不初始化]
new 类型名[数组长度] ( ): 加括号,则与执行 "new T( )" 所进行初始化的方式相同 [
小括号里不能带有任何参数]
eg: int *p = new int[10]( ) 可以方便地为动态创建的数组用0值初始化
delete删除数组: 要在指针名前前加"[ ]"
delete[ ] 指针名;
拓展:C++可以将数组建立和删除过程封装起来,形成一个动态数组类
在动态数组类中,通过类的成员函数访问数组元素,每次访问之前检查下标是否越界
用C++的 assert(
断言)实现:
assert是C++的assert头文件中定义的一个宏,用来判断一个条件表达式的值是否为ture
如果不为true,则程序会中止,并且报告出错误,这样就很容易将错误定位
一个程序一般可以以两种模式编译—调试模式(
debug)和发行模式(
release): assert 只能在调试模式下生效,而在发行模式下不执行任何操作
assert 只是检查程序本身的逻辑错误,而用户的不当输入造成的错误,应用其他方法加以处理
- 多维数组
new 类型名 T [数组第1维长度][数组第2维长度]……;
其中:
数组第一维长度:可以是任何结果为正整数的表达式,而其他各维数组长度必须是结果为正整数的常量表达式
注意:若内存申请成功,new运算返回一个指向新分配内存的首地址的指针,但不是T类型的指针,而是一个指向T类型的指针
eg: (错误) float *fp;
fp = new float[10][25][10]; 错误原因: new操作产生的是一个指向25*10的二维float类型数组的指针,而fp是指向float型数据的指针
(正确)
float(*cp)[25][10];
cp = new float[10][25][10];
删除依旧简单: delete[] cp; (仅管是多维,但一次就可以删除释放)