您的当前位置:首页正文

C语言动态存储管理的实现及常见问题分析

2024-04-20 来源:爱go旅游网
维普资讯 http://www.cqvip.com 第19卷第3期 郑州铁路职业技术学院学报 Journal ofZhengzhou Railway Vocational&Technical College Vo1.19 No.3 Sep.2007 2007年9月 C语言动态存储管理的实现及常见问题分析 毕喜 荡 (郑州铁路职业技术学院 河南郑州摘450052) 要:动态存储管理是C语言编程的重要内容,其概念抽象、运用灵活,给程序设计的学习带来一定的困 难。针对这一问题,首先应研究C语言动态存储管理的实现方法,并对实际运用中容易出现的问题及其危害性进 行分析,同时给出相应的解决方法,以保证程序正确、高效地执行。 关键词:C语言动态存储管理 内存分配 数据空间的存储管理一般可分为静态存储管理和动 态存储管理两种方式。静态存储管理是指在编译时就能 确定每个数据目标在运行时刻的存储空间需求,因而在 编译时就可以给它们分配固定的内存空间。这种分配策 略要求程序代码中不允许有可变数据结构(比如可变数 组)的存在,也不允许有嵌套或者递归的结构出现,因为 它们都会导致编译程序无法计算准确的存储空间需求。 但是在实际应用中,经常遇到事先无法确定有多少数据 指向该字符数组的指针,并把该指针赋予指针变量pc。 1.2带计数和清0的动态存储分配函数ealloe。其 函数原型是:void calloc(unsined ignt n,unsined ignt size)。作用是在内存动态存储区中分配n块长度为size 字节的连续区域。函数的返回值为该区域的首地址,如 果分配不成功就返回NULL。calloc函数与malloc函数 的区别在于一次可以分配n块区域,并且分配之后把存 储块里全部清0(初始化为0值)。例如:ps=(struct stu )calloc(2,sized(struct stu));其中的sized(struet stu) 是求stu的结构长度。因此该语句的含义是:按stu的长 度分配2块连续区域,并强制转换为stu类型,然后把其 首地址赋予指针变量ps。 要存储的情况,此时就不能采用静态存储。为此,c语言 中引入了动态存储管理机制,以满足应用需要。动态存 储管理在程序执行的过程中动态地分配或回收存储空 间。这种方式不需要预先分配存储空间,而是由系统根 据程序的需要即时分配。本文讨论了c语言动态存储管 理的实现方法,并结合实例对动态存储管理中的常见错 误进行了分析,同时给出了正确的使用方法。 1动态存储管理的实现 1.3动态存储释放函数free。其原型是:void free (void P)。作用是释放指针P所指向的一块内存空间, 使这部分内存空间能被其它变量使用。参数P是一个任 意类型的指针变量,它指向被释放区域的首地址,被释放 区域应是调用malloc或calloc函数所分配的区域。如果 P是空指针,fere不执行任何操作。注意,P所指向的内 c语言的动态存储管理由一组标准库函数实现,其 原型在标准文件<stdlib.h>里描述,需要用这些功能时 应包含这个文件。与动态存储分配有关的函数共有四 个: 存区释放后不允许再通过P去访问,否则可能引起死机 或其它灾难性后果。 1.4分配调整函数realloc。其函数原型是:void realloc(void P,unsined ignt size)。作用是将P所指向 1.1存储分配函数malloc。其函数原型是:void malloc(unsigned int size)。作用是在内存的动态存储区 中分配一块长度为size字节的连续区域。函数的返回值 为该区域的首地址,如果不能满足申请(例如内存不足) 就返回空指针NULL。参数size是一个无符号整数。例 如:pc=(char )malloc(100),表示分配100个字节的 的存储空间的大小重新分配为size个字节的连续区域。 参数size表示现在需要的存储块大小。在调用realloc 时,指针变量P的值必须是调用calloc或malloe函数时 返回的值。realloc在无法满足新要求时返回NULL,同时 也保持P所指的存储块的内容不变。如果能够满足要 内存空间,并强制转换为字符数组类型,函数的返回值为 收稿日期:2007一o5—17 作者简介:毕喜彦(1971一)男,河南南阳人,郑州铁路职业技术学院信息工程系讲师。 维普资讯 http://www.cqvip.com

求,rIealloc就返回一片存放大小为size的数据存储块,并 保证该块的内容与原块一致;如果新块比原块小,原数据 块里大小为size范围内的那些数据将保留;如果新块比 原块大,原有数据存放在新块的前面部分,新增的部分不 自动初始化。 2动态存储管理常见问题 行带来了隐患。 2.5对动态分配的内存空间越界访问 系统对动态分配的内存空间的使用不做任何检查, 编程序的人需要保证使用的正确性,绝不可以超出实际 存储区域的范围进行访问。例如下面的程序段: int i=O, P; 2.1不检查内存分配结果 内存分配并不总是成功的,malloc、calloc和realloc 函数分配失败时均返回NULL指针,而对NULL指针进 行写操作是不合法的,会影响程序的正确执行。因此,必 P=(int )malloc(sizeof(int) 10); f(P!=NULL)i {while(i<=10) { P=i;i++;p++;} 须检查内存分配的成功与否。在实际应用中,常用以下 语句来防错: if((P=(… )malloc(…))!=NULL) {..…・/ 如果分配成功,执行相应操作 /} 2.2动态释放非动态申请的变量 这类问题是对非动态申请的指针变量动态释放,如 开始声明int P=&a,后来用free(P)来释放指针P,这 样将出现运行错误。因为这里的指针P不是动态分配 的,静态变量的空间在程序运行过程中是不能改变的,它 在生存期结束后由系统自动释放。 2.3使用释放后的内存空间 内存一旦释放,就不能再利用,否则会导致未定义行 为。无法保证程序的正确运行。下面程序段显示了这种 错误: while(P!=NULL) { e(p); P=P一>next;} 该例调用free(P)将指针P释放后,又使用P的值, 这是错误的。正确的使用为: while(P!=NULL) {q=P一>next; free(P); P=q;} 2.4重复释放同一内存空间 这类问题多数是由于编译器没有分析别名引起的, 如下面的程序段: char P, q; P=(char )malloc(sizeof(char) 10); fi(P!=NULL) {strcpy(P, ̄hello”); q P; strcpy(q,"china”); fere(P); e(q);} 这个例子中先为P动态分配了空间,然后使指针q 指向P所指的空间,这时指针p,q已成为指针别名,但是 编译器无法检查出,以致于编译到free(P),free(q)时仍 然不能报错,这就导致同一内存空间重复释放,为程序运 24 } . 上例中动态申请的空间只能存储1O个整型数据,但 循环体却执行了11次,最后一次循环时造成指针P越 界,这种越界访问给C程序带来隐患甚至是致命的错误。 2.6释放连续内存空间时指针位置不正确 通过动态分配得到的内存空间是一个整体,只能作 为一个整体管理,释放时也必须对空间整体释放,而不能 单独释放某个空间,即释放时指向连续空间的指针必须 在分配空间的首部,否则对连续申请的内存空间不能正 确释放。如下例所示: int P; P=(int )m ̄Uoc(sizeof(int) 10); fi(P!=NULL) {f0r(i=0;i<10;i++) { P=i i;P++;f e(p);} 指针P不能被正确释放,因为释放时指针P没有返 回到申请空间的首部。应该在循环前将P的值赋给另一 个指针变量如q,最后释放q所指的空间。 2.7未释放动态申请的内存空间而造成的内存泄 漏 常说的内存泄漏是指堆内存的泄漏。堆内存是指程 序从堆中分配、大小任意、使用完后必须显式释放的内 存。应用程序一般使用malloc等操作从堆中分配一块内 存,使用完后程序必须负责调用相应的free函数释放该 内存块,否则,这块内存就不能被再次使用,即出现内存 泄漏。如下面的程序段: while(i<MAX) {P (double )malloc(sizeof(double); fi(P!=NULL) { P=pow(x,i); i++;} } fere(p); 循环体中对MAX一1个对象进行了动态分配空间. 但最后只对一个进行释放,前面的MAX一2个对象的空 间将被泄漏。 (下转第28页) 维普资讯 http://www.cqvip.com

盘。仪表原理图可用扫描仪扫描或用AutoCAD、word、 PowerPoint自带的绘图功能绘制。绘制图形虽然麻烦,但 比扫描得到的图形效果好,并且可任选颜色及设置简单 的动画。实物图片通过扫描或下载的方式搜集,用Win— dows自带的“画图”程序处理。 3.背景画面的设计 背景画面是多媒体课件所有视觉元素的载体,对课 件的色彩基调具有一定的调控作用。本课件的模板采用 效果,在演示中声音和图形动画相结合,更能清晰的说明 演示内容,弥补图形的不足。 7.课件的合成 PowerPoint 2003支持多种媒体格式,如avi电影、gif 动画等。为了防止PowerPoint文件字节过大,可把Flash 动画导入PowerPoint中。本课件采用“嵌入”的方式导入 Flash动画,用“插入”而非“粘贴”的方式导入图片,用 “插入”而非“超级连接”的方式引入视频,大大减小了文 网上下载的《108个课件模板》加以修改创新制作而成。 件的字节数。 4.文字 8.课件的打包 每一种字体都有它自身的表情。如黑体有醒目严肃 PowerPoint2003带有“打包成CD”的功能。通过它 的感觉,宋体、楷书有端庄刚直的表情,仿宋、行书有清秀 可以将演示文稿打包到CD上,以便在脱离PowerPoint的 自由的意趣等。因此,课件中选用字体时,应该按讲课内 环境下也能够运行。另外打包到CD的功能还允许选择 容的精神而定,这样才能表里一致,发挥出字体的感染 是否一旦将CD插入计算机光驱后就自动播放课件。因 力。至于字体的变化形式,有透视法、立体投影、空心变 此,本课件利用这个功能制作出了自动播放的多媒体光 化等,也可以用Photoshop加以处理,加强其装饰意义,使 盘。 之美化。 三、结束语 5.动画的制作 本课件充分利用了Flash的图文、颜色及动态显示功 文字的内容用图形、图像无法准确表达时,动画可以 能。使用时,学生象面对一本活的书,它图文并茂,使学 很好的胜任这一工作。本课件主要采用二维动画的方式 习更具吸引力,学习者掌握主动权,计算机的每一步反应 表现各种仪表的内部动作和工质的流动。动作复杂的动 都是学习者经过思考后,亲自“下令”而逐步完成的。画 画,如压力弹簧管的指针转动、管道中流体的流动及流束 面生动,使枯燥而单调的书本知识变为生动活泼的动画 的变化、氧浓差电势产生过程中的氧离子的移动等采用 形式。解决了仪表教学中不易在黑板上简单演示的缺 FlashMX 2004制作。对于简单的动画,如热电偶和热电 点,不但减轻了老师的工作量,也使学生更易于理解。 阻的构成、汽包水位计的构成等,为保证演示的流畅性, 采用PowerPoint自身的动画功能来实现。 参考文献 6.动画配音 [1]朱祖涛.热工测量及仪表[M].中国电力出版社,2002. Flash提供的音频控制的方法可以让声音独立于时 [2]郝文化.多媒体设计与制作[M].清华大学出版社,2005. 间轴播放,也可以专为动画配上一段音乐,或是为按钮添 [责任编辑:黄玉田1 加某种声音,达到画龙点腈的作用。在课件中加入声音 (上接第24页) 分配给P的内存空间未释放,不能再被访问,该内存空间 2.8指针赋值不当而造成的内存泄漏 便成了无效内存块,造成内存空间的浪费。因此,在执行 在c语言中指针之间可以互相赋值,但如果赋值不 P=q之间应该对P所占内存加以释放,也就是在语句P 当,将可能造成一部分内存空问的丢失,即这部分空间不 =q之间,添加语句free(p)。 能再被该程序及其后任何程序访问。例如下面的程序 3结束语 段: 内存区域是有限的,每个c语言编程者在进行动态 int P, q; 存储分配时,都应尽量节省资源,当所分配的内存区域不 P=(int})malloc(sizeof(int)); 再使用时,应该及时将它释放,以便其它变量和程序使 q=(int})malloc(sizeof(int)); 用,从而提高存储空间的利用率。 if(P!=NULL) P=10: 参考文献 fi(q!=NULL) [I]谭浩强.c语言设计[M],北京:清华大学出版社,2000. q=20; [2]王江涛.c程序设计中的指针探究[J].电脑知识与技术,2006,26 P q; f101);169—170. pfinif(”%d,%d\n , P, q); [3]吕维梅,刘竖.C/C++程序安全漏洞的分类与分析[J].计算机 工程与应用,2005,5(14):123—125. 该例中指针P和q通过内存分配获得系统内存,执 行P=q后,P和q均指向分配给q的内存空间,而原先 [责任编辑:方艳] 28 

因篇幅问题不能全部显示,请点此查看更多更全内容