C语言中的内存泄漏原因及对策分析

来源 :中国新通信 | 被引量 : 0次 | 上传用户:sima1969
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  在C语言程序设计中,内存泄漏几乎是很难避免的,C程序产生泄漏内存,则运行速度会逐渐变慢,并最终停止运行;如果产生覆盖内存,程序会变得非常脆弱,很容易受到恶意用户的攻击。内存泄漏是一种隐性危害,它们很难被发现,通常不能在相应的源代码中找到错误,需要仔细分析与专门的检测工具才能发现。
  一、内存泄漏的定义
  通常我们所说的内存泄漏,是指分配出去的内存在使用之后没有释放掉,没有回收,长此以往,会造成没有足够的内存可以分配。一般表现为运行时间越长,占用的内存越多,最终导致系统奔溃。一般的内存泄漏是指堆內存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显式释放的内存。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。
  二、内存泄漏原因分析
  2.1 C语言内存分配情况
  在C语言中,根据数据在内存中存在的时间(生存周期)不同,将内存空间分为三个区:1)程序区:用于存储程序的代码,即程序的二进制代码。2)静态存储区:用于存储全局变量和静态变量,这些变量的空间在程序编译时就已经分配好了。3)动态存储区:用于在程序执行时分配的内存,又分为:堆区(heap)和栈区(stack)。堆区:用于动态内存分配,程序运行时由内存分配函数在堆上分配内存。在C语言中,只能使用指针才能动态的分配内存。栈区:在函数执行时,函数内部的局部变量和函数参数的存储单元的内存区域,函数运行结束时,这些内存区域会自动释放。
  2.2 C语言动态内存分配
  在C语言中用内存分配函数来实现内存的动态分配,这些函数有:malloc()和realloc()等函数。malloc(): 使用这个函数时需要包含头文件。使用该函数需要指定要分配的内存字节数作为参数,例如:
  int *pNumber=(int *) malloc(100)
  这条语句分配了100个字节的内存,并把这个内存块的地址赋给pNumber,这个内存块可以保存最大25个int值,每个int占4个字节。如果不能分配请求的内存,malloc()会返回一个null指针。
  2.3 释放动态分配的内存
  堆上分配的内存会在整个应用程序结束之后,由操作系统负责回收,但最好是在使用完这些内存后立即释放。如果不释放,会引起内存泄漏,极大占用系统资源,可能会产生各种未知的错误。所以,必须使用free()函数释放内存,参数是内存地址(指针),例如:free(pNumber),依上例。
  三、内存泄漏避免的方法
  3.1正确使用malloc函数分配内存
  malloc是一个函数,专门用来从堆上分配内存。使用malloc函数需要几个要求:内存分配给谁?分配多大内存?是否还有足够内存分配? 内存将用来存储什么格式的数据?分配好的内存在哪里? 如果这5点都确定,那内存就能分配。下面看看malloc的原型:(void *)malloc(int size)
  malloc函数的返回值是一个void类型的指针,参数为int类型的数据,即申请分配的内存大小,单位是字节。内存分配成功之后,malloc函数返回这块内存的首地址,你需要一个指针来接受这个地址。也就是说这块内存将来要用来存储什么类型的数据,如:
  char *p = (char *)malloc(100)
  在堆内存分配了100个字节的内存,返回这块内存的首地址,把地址强制转换成char *类型后赋给char *类型的指针变量p;同时告诉我们这块内存将用来存储char类型的数据。你只能通过指针变量p来操作这块内存,这块内存本身没有名字,对它的访问是匿名访问。但是,不一定每次malloc函数都能成功分配到内存。既然malloc函数申请内存存在不成功的可能,那我们在使用指向这块内存的指针时,必须用if( NULL != p)语句上来验证内存分配确实成功了。
  3.2 正确使用free函数释放内存
  既然有分配,那就必须有释放,不然的话,有限的内存就会用光,而没有释放的内存却占用空间,与malloc对应的就是free函数了。free函数只有一个参数,就是所要释放的内存块的首地址(指针)。按上例,则为:free(p) 。free函数其实它就做了一件事:斩断指针变量和这块内存的对应关系。free函数就是把这块内存和p之间的关系斩断;p本身的值并没有改变或者消失,即指针变量p本身保存的地址并没有改变,那块被释放的内存里面保存的值也没有改变。这就是free函数的功能,一个malloc对应一个free,是一夫一妻制。在使用free(p)函数内存释放后,指针变量p本身保存的地址并没有改变,那我们必须需重新把p的值变为NULL:p = NULL。如果没有把该指针置NULL,这个指针就成为了“悬空指针”,这是很危险的,且也是经常出错的地方。
  四、结论
  从用户使用程序的角度来看,作为一般的用户,根本就感觉不到内存泄漏的存在,真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存,给应用程序带来极大的不稳定性,要避免这个问题,需要在代码设计上入手,养成良好的编码习惯和规范。
  参 考 文 献
  [1] C程序设计 .唐浩强 .北京:华大学出版社. 1991年7月
  [2]吕维梅,刘坚. C/C++程序安全漏洞的分类与分析[J] . 计算机工程与应用,2003:39(6):37-40.
其他文献
为加快推进现代公共文化服务体系建设,提高全省基层图书馆管理与服务水平,促进基层图书馆快速发展,由辽宁省图书馆和辽宁省图书馆学会举办的“构建现代公共文化服务体系——辽宁
4LX-1.8型小型自走式联合收割机试验山西省农机鉴定站吴庆波4LX-1.8型小型自走式联合收割机是由山西省运城地区农机研究所组织研制的。它主要由割台、输送、脱粒清选、接粮部分和液压、行走
介绍了大数据的产生以及图书馆具有的大数据特征,阐述了大数据环境下学科化服务的必要性,分析了通过学科化服务参与文献资源建设、以学科化为基础适当调整文献资源布局、充分
《走一步,再走一步》又译作《悬崖上的一课》,是美国作家、心理学家莫顿·亨特的代表作。讲述"我"小时候在悬崖边发生的故事,以及这段经历给"我"一生的影响。语文教材虽几次
在我国南方地区,日照情况较好,光伏空调具有较好的气候适用性。目前针对光伏空调的研究主要基于小型光伏空调系统。对位于珠海的光伏直驱变频空调(离心式水冷冷水机组)系统进
独立网络面临两大问题,包括网络生存时间和系统数据传输的安全性,论文提出以动态成簇方式保证网络各节点生存能力的平衡,将基于PKI的64位非对称加密算法引入网络应用服务端的
在11月29日举行的2019(第三届)“中国制造2025”企业家国际论坛上,获颁“改革开放再出发·强盛中国制造业一领军企业&最佳投资工厂&领军人物评选”两项大奖。其中,台达-
文言文与古诗词,是我们这个民族历史悠久的见证,是我们古代文化源远流长的再现,是古代文化长廊中的绚烂奇葩。作为炎黄子孙,熟读这些历久弥新又饱含温度的文字,才能感知我们民族的伟大,感受古代文化的魅力,接受古典语言的浸润,提升人文语言的素养。  正因为如此,在全国各地的语文教材中,不管是地方版本的教材还是部编版本的教材,文言文与古诗词都占了较大的比例。因而文言文与古诗词的教学,也就成了语文老师必须琢磨与
中考语文复习时间紧,内容多,如何对学生进行有效的复习指导,帮助学生把所学知识系统化,引领他们搭建起知识框架,实现课内向课外的迁移,这些都至关重要。作为语文教师只有树立正确的复习教学理念,才能进行高效地复习教学工作,而比较法就是一种行之有效的复习方法。所谓的比较法就是在复习时,以某一个知识点为联系点,把与之有关的内容联系起来比较其异同的一种教学方法。通过联系比较,帮助学生分清概念,从而构建一个完整的
语文课堂教学中,不少老师都苦恼于学生的阅读能力不高或者根本就没有阅读理解能力。这无疑在给语文老师敲响警钟:只有教会学生如何解读文本,才能提高学生阅读能力!叶圣陶老先