友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
喜书网 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

C语言实例教程(PDF格式)-第24章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




数以及在函数中定义的局部变量的内存区域。帧变量通常被称作自动 

变量,这是因为编译器自动为它们分配所需的内存。  



帧分配有两个主要特征,首先,当我们定义一个局部变量是,编译器 

将在堆栈帧上分配足够的空间来保存整个变量,对于很大的数组和其 

它数据结构也是这样;其次,当超过其作用域时,帧变量将被自动的 

删除。下面举一个帧分配的例子:  



int Func(int Argu1;int Argu2) // 编译器将在堆栈帧上为函数参数变量分配空间  



{  



// 在堆栈上创建局部对象  



char szDatum'256''256';  


…………………………………………………………Page 148……………………………………………………………

。。。  



// 超过作用域时将 自动删除在堆栈上分配的对象  



}  



对于局部函数变量,其作用域转变在函数退出时发生,但如果使用了 

嵌套的花括号,则帧变量的作用域将有可能比函数作用域小。自动删 

除这些帧变量非常之重要。对于简单的基本数据类型(如整型或字节 

变量)、数组或数据结构,自动删除只是简单的回收被这些这是所占 

用的内存。由于这些变量已超出其作用域,它们将再也不可以被访 

问。对于C++对象,自动删除的过程要稍稍复杂一些。当一个对象被 

定义为一个帧变量时,其构造函数在定义对象变量时被自动的调用, 

当对象超出其作用域时,在对象所占用的内存被释放前,其析构函数 

先被自动的调用。这种对构造函数和析构函数的调用看起来非常的简 

便,但我们必须对它们倍加小心,尤其是对析构函数,不正确的构造 

和释放对象将可能对内存管理带来严重的问题。在本书的第二章中我 

们曾经历过其中的一种——指针挂起。  



在帧上分配对象的最大的优越性在于这些对象将会被自动的删除,也 

就是说,当你在帧上分配对象之后,不必担心它们会导致内存漏损 

(memory   leak)。但是,帧分配也有其不方便之处,首先,在帧上分 

配的变量不可以超出其作用域,其中,帧空间往往是有限的,因此, 

在很多情况下,我们更倾向于使用下面接着要讲述的堆分配来代替这 

里所讲述的帧分配来为那些庞大的数据结构或对象分配内存。  



堆是为程序所保留的用于内存分配的区域,它与程序代码和堆栈相隔 

离。在通常情况下,C程序使用函数malloc和free来分配和释放堆内 

存。调试版本 (Debug   version)的MFC提供了改良版本的C++内建运算 

符new和delete用于在堆内存中分配和释放对象。  



使用new和delete代替malloc和free可以从类库提供的增强的内存管 

理调试支持中得到好处,这在检测内存漏损时非常之有用。而当你使 

用MFC的发行版本 (Release   version)来创建应用程序时,MFC的发行 

版本并没有使用这种改良版本的new和delete操作符,取而代之的是 

一种更为有效的分配和释放内存的方法。  



与帧分配不同,在堆上可分配的对象所占用的内存的总量只受限于系 

统可有的所有虚拟内存空间。  



以下的示例代码对比了上面讨论的内存分配方法在为数组、数据结构 

和对象分配内存时的用法:  


…………………………………………………………Page 149……………………………………………………………

使用帧分配为数组分配内存:  



{   



const int BUFF_SIZE = 128;   



// 在帧上分配数组空间  



char myCharArray'BUFF_SIZE';  



int myIntArray'BUFF_SIZE';  



// 所分配的空间在超出作用域时自动回收  



}  



使用堆分配为数组分配内存:  



const int BUFF_SIZE = 128;  



// 在堆上分配数组空间  



char* myCharArray = new char'BUFF_SIZE';   



int* myIntArray = new int'BUFF_SIZE';  



。。。  



delete '' myCharArray;  



delete '' myIntArray;  



使用帧分配为结构分配内存:  



struct MyStructType { int topScore;};  



void SomeFunc(void)  



{  



// 帧分配  



MyStructType myStruct;  



// 使用该结构  



myStruct。topScore = 297;  



// 在超出作用域时结构所占用的内存被自动回收  



}  


…………………………………………………………Page 150……………………………………………………………

使用堆分配为结构分配内存:  



// 堆分配  



MyStructType* myStruct = new MyStructType;  



// 通过指针使用该结构  



myStruct…》topScore = 297;  



delete myStruct;  



使用帧分配为对象分配内存:  



{  



CMyClass myClass; // 构造函数被自动调用  



myClass。SomeMemberFunction(); // 使用该对象  



}  



使用堆分配为对象分配内存:  



// 自动调用构造函数  



CMyClass *myClass=new CMyClass;   



myClass…》SomeMemberFunction(); // 使用该对象  



delete myClass; // 在使用delete的过程中调用析构函数  



  l 注意:  



  l 一定要记住一个事实,在堆上分配的内存一定要记得释放,对于 

    使用运算符new分配的内存,应当使用delete运算符来释放;而使 

    用malloc函数分配的内存应当使用free函数来释放。不应 当对同 

    一内存块交叉使用运算符new、delete和函数malloc、free (即使 

    用delete运算符释放由malloc函数分配的内存,或使用free函数 

    释放由new运算符根本的 内存),否则在MFC的调试版本下将会导致 

    内存冲突。  



对固定大小的内存块,使用运算符new和delete要比使用标准C库函数 

malloc和free方便。但有时候我们需要使用可变大小的内存块,这 

时,我们必须使用标准的C库函数malloc、realloc和free。下面的示 

例代码创建了一个可变大小的数组:  


…………………………………………………………Page 151……………………………………………………………

#include   



#include   



#define UPPER_BOUND 128  



void main()  



{  



int *iArray=(int *)malloc(sizeof(int));  



for (int i=0;i
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!