当前位置:鱼C工作室 >C++ > 查看文章

动态内存管理 – C++快速入门33

动态内存管理

 

让编程改变世界

Change the world by program


 

动态内存管理

 

到目前为止不了,小甲鱼给大家所讲解的每一个示例程序在完成它的任务时所使用的内存空间都是固定不变的。

这个固定不变的内存空间其不实是在编写程序时候就可以知道和确定(一般以变量的形式)。

这些程序都不能再程序运行期间动态增加或减少内存空间。

 

但小时候,性感而卡哇伊的物理老师告诉我们:这个时间没有完全静止的东西!现实世界是动态的!

所以,C++也必须支持动态管理内存,而这节课,小甲鱼正式要跟大家介绍这个。

 

你见过要求用户输入的文本必须不多不少包含多少个字符的程序吗?不可能吧?!

在很多时候,需要存储的数据量到底有多大在事先往往是一个未知数,要想处理好这类情况,就需要在C++程序里使用动态内存。

 

动态内存支持程序猿创建和使用种种能够根据具体需要扩大和缩小的数据结构,它们只受限于计算机的硬件内存总量和系统特殊约束。

接下来,我们将学到如何以这种灵活的方式与内存打交道。

 

静态内存

 

静态内存就是我们此前一直在使用的东西:变量(包括指针变量)、固定长度的数组、某给定类的对象。

我们可以在程序代码里通过它们的名字或者地址来访问和使用它们。

 

使用静态内存的最大弊端是,你不得不在编写程序时为有关变量分配一块尽可能大的内存(以防不够存放数据)。

一旦程序开始运行,不管实际情况如何,那个变量都将占用那么多的内存,没有任何办法能改变静态内存的大小。

 

动态内存

 

动态内存由一些没有名字、只有地址的内存块构成,那些内存块是在程序运行期间动态分配的。

它们来自一个由标准 C++ 库替你管理的”大池子”(装B术语称之为”内存池”)

从内存池申请一些内存需要用 new 语句,它将根据你提供的数据类型分配一块大小适当的内存。

你不必担心内存块的尺寸问题,编译器能够记住每一种数据类型的单位长度并迅速计算出需要分配多少个字节。

如果有足够的可用内存能满足你的申请,new 语句将返回新分配地址块的起始地址。

 

如果没有足够的可用内存空间?那么 new 语句将抛出 std::bad_alloc 异常!

注意在用完内存块之后,应该用 delete 语句把它还给内存池。

另外作为一种附加的保险措施,在释放了内存块之后还应该把与之关联的指针设置为NULL。

 

图说编程:

int *i = new int;

int *i = new int;

 

delete i;

delete i;

 

i = NULL;

i = NULL;

 

NULL指针

 

有一个特殊的地址值叫做 NULL 指针。当把一个指针变量设置为 NULL 时,它的含义是那个指针将不再指向任何东西:

int *x;

x = NULL; // x 这时候啥都不指向

 

我们无法通过一个被设置为 NULL 的指针去访问数据。

事实上,试图对一个 NULL 指针进行解引用将在运行时被坚持到并将导致程序中止执行。

所以在用 delete 释放内存后,指针会保留一个毫无意义的地址,我们要将指针变量赋值为 NULL。

 

pay attention

 

请注意,静态内存这个术语与 C++ 保留字 static 没有任何关系。

静态内存意思是指内存块的长度在程序编译时被设定为一个固定的值,而这个值在程序运行时是无法改变的。

new 语句返回的内存块很可能充满”垃圾”数据,所以我们通常先往里边写一些东西覆盖,再访问它们,或者在类直接写一个构造器来初始化。

在使用动态内存时,最重要的原则是每一条 new 语句都必须有一条与之配对的 delete 语句,没有配对的 delete 语句或者有两个配对的 delete 语句都属于编程漏洞。(尤其前者,将导致内存泄漏)

 

为对象分配内存

 

为对象分配内存和为各种基本数据类型(int, char, float…)分配内存在做法上完全一样。

用 new 向内存池申请内存

用 delete 来释放内存

 

这个概念其实我们老早前就给大家演示了:在虚函数那一讲中有木有?!

我们再用一个栗子给大家巩固巩固之前的知识:

Example.cpp(课件及源代码下载

 

pay attention

 

搞对象的时候,千万不要忘记把方法声明为虚方法,如仍有疑问请回顾《C++快速入门》第二十三讲 —— 虚方法。

在重新使用某个指针之前千万不要忘记调用 delete 语句,如果不这样做,那个指针将得到一个新内存块的地址,而程序将永远也无法释放原先那个内存块,因为它的地址已经被覆盖掉了。

 

请记住,delete 语句只释放给定指针变量正指向的内存块,不影响这个指针。

在执行 delete 语句之后,那个内存块被释放了,但指针变量还依然健在哦。


为您推荐

报歉!评论已关闭.