第七章动态内存分配 7.1堆内存分配 7.2链表与链表的基本操作 7.3栈与队列的基本操作及其应用 7.4二叉树 7.5MFc对象 Windows和对象的关系
7.1 堆内存分配 7.5 MFC对象和Windows对象的关系 7.4二叉树 7.3 栈与队列的基本操作及其应用 7.2 链表与链表的基本操作 第七章 动态内存分配
7.1惟向存分配 7.1.1堆内存的分配与释放 7.1,2堆对象与构造函数 7.1.3浅拷贝与深拷贝 DU
7.1 堆内存分配 7.1.1堆内存的分配与释放 7.1.2 堆对象与构造函数 7.1.3 浅拷贝与深拷贝
71堆角存的分配与放 当程序运行到需要一个动态分配的变量或对象时,必须向系统 申请取得堆中的一块所需大小的存贮空间,用于存贮该变量或对 象。当不再使用该变量或对象时,也就是它的生命结束时,要显 式释放它所占用的存贮空间,这样系统就能对该堆空间进行再次 分配,做到重复使用有限的资源。 在C++中,申请和释放堆中分配的存贮空间,分别使用new和 deletel的两个运算符来完成,其使用的格式如下: 指针变量名=new类型名(初始化式); delete指针名; new运算符返回的是一个指向所分配类型变量(对象)的指 针。对所创建的变量或对象,都是通过该指针来间接操作的,而 DU
7.1.1 堆内存的分配与释放 当程序运行到需要一个动态分配的变量或对象时,必须向系统 申请取得堆中的一块所需大小的存贮空间,用于存贮该变量或对 象。当不再使用该变量或对象时,也就是它的生命结束时,要显 式释放它所占用的存贮空间,这样系统就能对该堆空间进行再次 分配,做到重复使用有限的资源。 在C++中,申请和释放堆中分配的存贮空间,分别使用new和 delete的两个运算符来完成,其使用的格式如下: 指针变量名=new类型名(初始化式); delete 指针名; new运算符返回的是一个指向所分配类型变量(对象)的指 针。对所创建的变量或对象,都是通过该指针来间接操作的,而 动态创建的对象本身没有名字
71,1堆角存的分配与释放 1.用初始化式( initializer)来显式初始化 堆 例如: int*pi=new int(o) 2.当p生命周期结束时,必须释放p所指向的目标 delete pli 注意这时释放了p所指的目标的内存空间,也就是撤销了该目标, 称动态内存释放( dynamic memory deallocation),但指针pi 本身并没有撤销,它自己仍然存在,该指针所占内存空间并未释放。 DEU
7.1.1 堆内存的分配与释放 1.用初始化式(initializer)来显式初始化 例如: int *pi=new int(0); 2.当pi生命周期结束时,必须释放pi所指向的目标: delete pi; 注意这时释放了pi所指的目标的内存空间,也就是撤销了该目标, 称动态内存释放(dynamic memory deallocation),但指针pi 本身并没有撤销,它自己仍然存在,该指针所占内存空间并未释放。 堆 Pi 0
71,1堆角存的分配与释放 1.用初始化式( initializer)来显式初始化 堆 例如: int piane 当pi生命周期结束时,必须释放p所指向的目标 delete pi; 注意这时释放了p所指的目标的内存空间,也就是撤销了该目标, 称动态内存释放( dynamic memory deallocation),但指针pi 本身并没有撤销,它自己仍然存在,该指针所占内存空间并未释放。 DEU
1.用初始化式(initializer)来显式初始化 例如: int *pi=new int(0); 2.当pi生命周期结束时,必须释放pi所指向的目标: delete pi; 注意这时释放了pi所指的目标的内存空间,也就是撤销了该目标, 称动态内存释放(dynamic memory deallocation),但指针pi 本身并没有撤销,它自己仍然存在,该指针所占内存空间并未释放。 7.1.1 堆内存的分配与释放 堆 Pi
71堆角存的分配与放 对于数组进行动忞分配的格式为 指针变量名=neW类型名[下标达式]; delete[]指向该数组的指针变量名; DU
7.1.1 堆内存的分配与释放 对于数组进行动态分配的格式为: 指针变量名=new 类型名[下标表达式]; delete [ ] 指向该数组的指针变量名;
71堆角存的分配与放 【例71】动态数组的建立与撒销 include *include void minot int n; char *pci cout>n; pc= new char[nP∥/ strcpy(pc"堆内存的动态分配" cout<<pc<<endi delete[]pc;/撤销并释放pc所指向的n个字符的内存空间 return i 1 DU
7.1.1 堆内存的分配与释放 【例7.1】动态数组的建立与撤销 #include #include void main(){ int n; char *pc; cout>n; pc=new char[n]; // strcpy(pc,"堆内存的动态分配"); cout<<pc<<endl; delete []pc; // 撤销并释放pc所指向的n个字符的内存空间 return ; }
71堆角存的分配与放 动态分配的三个特点:首先,变量n在编译时没有 确定的值,而是在运行中输入,按运行时所需分配堆空 间,这一点是动态分配的优点,可克服数组“大开小用” 的弊端,在第六章中表,排序与查找中的算法,若用动 态数组,通用性更佳。 delete[]pc是将n个字符的空间 释放,而用 delete pc则只释放了一个字符的空间;其 次如果有一个char*pc1,令pc1=p,同样可用 delete []pc1来释放该空间。尽管C++不对数组作边界检查 但在堆空间分配时,对数组分配空间大小是纪录在案的 第三,没有初始化式( initializer),不可对数组初始 化 DU
7.1.1 堆内存的分配与释放 动态分配的三个特点:首先,变量n在编译时没有 确定的值,而是在运行中输入,按运行时所需分配堆空 间,这一点是动态分配的优点,可克服数组“大开小用” 的弊端,在第六章中表,排序与查找中的算法,若用动 态数组,通用性更佳。delete []pc是将n个字符的空间 释放,而用delete pc则只释放了一个字符的空间;其 次如果有一个char *pc1,令pc1=p,同样可用delete [] pc1来释放该空间。尽管C++不对数组作边界检查, 但在堆空间分配时,对数组分配空间大小是纪录在案的。 第三,没有初始化式(initializer),不可对数组初始 化
71堆角存的分配与放 指针使用的几个问题: 1.动态分配失败。回一个空指 ,表示 生了异常, 分配失败 2.指针删除与堆空间释放。删除一个指针p( delete p;) 实际意思是删除了p所指的目标(变量或对象等),释 放了它所占的堆空间,而不是删除p本身,释放堆空间 后,p成了空悬指针 DU
7.1.1 堆内存的分配与释放 指针使用的几个问题: 1.动态分配失败。返回一个空指针(NULL),表示 发生了异常,堆资源不足,分配失败。 2.指针删除与堆空间释放。删除一个指针p(delete p;) 实际意思是删除了p所指的目标(变量或对象等),释 放了它所占的堆空间,而不是删除p本身,释放堆空 间 后,p成了空悬指针
71堆角存的分配与放 3 emory leak)和 neW与 delete是配对使用的, delete只能释放堆空间 如果new返回的指针值丢失,则所分配的堆空间无 法回收,称内存泄漏,同一空间重复释放也是危险 的,所以必须妥善保存new返回的指针,以保证不 发生内存泄漏,也必须保证不会重复释放堆内存空 间 4.动态分配的变量或对象的生命期。无名对一的 用域,比如在 返国仍可使 Sto DEU
7.1.1 堆内存的分配与释放 3.内存泄漏(memory leak)和重复释放。new与 delete 是配对使用的, delete只能释放堆空间。 如果new返回的指针值丢失,则所分配的堆空间无 法回收,称内存泄漏,同一空间重复释放也是危险 的,所以必须妥善保存new返回的指针,以保证不 发生内存泄漏,也必须保证不会重复释放堆内存空 间。 4.动态分配的变量或对象的生命期。无名对象,它的 生命期并不依赖于建立它的作用域,比如在函数中 建立的动态对象在函数返回后仍可使用。我们也称 堆空间为自由空间(free store)就是这个原因