在堆上分配内存――摘自《编程修养》 :: 一切只是开始
来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=137648 存档链接: https://web.archive.org/web/20041130163549id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=137648
一切只是开始 现征用为 loveunix 临时信息发布站 <<<轻而易举多接了个硬盘 | 首页 | WinCVS简明操作指南>>> 在堆上分配内存――摘自《编程修养》 时间:04/04/12 在堆上分配内存 ――――――――― 可能许多人对内存分配上的“ 栈 stack ”和“ 堆 heap ”还不是很明白。包括一些科班出身的人也不明白这两个概念。我不想过多的说这两个东西。简单的来讲,stack上分配的内存系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里。 stack一般是静态分配内存,heap上一般是动态分配内存 。 由malloc系统函数分配的内存就是从堆上分配内存。从堆上分配的内存一定要自己释放。用free释放,不然就是术语――“ 内存泄露 ”(或是“内存漏洞”)―― Memory Leak。于是,系统的可分配内存会随malloc越来越少,直到系统崩溃。还是来看看“栈内存”和“堆内存”的差别吧。 栈内存分配 ――――― char* AllocStrFromStack() { char pstr[100]; return pstr; } 堆内存分配 ――――― char* AllocStrFromHeap(int len) { char pstr; if ( len <= 0 ) return NULL; return ( char ) malloc( len ); } 对于第一个函数,那块pstr的内存在函数返回时就被系统释放了。于是所返回的char*什么也没有。而对于第二个函数,是从堆上分配内存,所以哪怕是程序退出时,也不释放,所以第二个函数的返回的内存没有问题,可以被使用。但一定要调用free释放,不然就是Memory Leak! 在堆上分配内存很容易造成内存泄漏,这是C/C++的最大的“克星”,如果你的程序要稳定,那么就不要出现Memory Leak。所以,我还是要在这里千叮咛万嘱付,在使用malloc系统函数(包括calloc,realloc)时千万要小心。 记得有一个UNIX上的服务应用程序,大约有几百的C文件编译而成,运行测试良好,等使用时,每隔三个月系统就是down一次,搞得许多人焦头烂额,查不出问题所在。只好,每隔两个月人工手动重启系统一次。出现这种问题就是Memery Leak在做怪了,在C/C++中这种问题总是会发生,所以你一定要小心。一个Rational的检测工作――Purify,可以帮你测试你的程序有没有内存泄漏。 我保证,做过许多C/C++的工程的程序员,都会对malloc或是new有些感冒。当你什么时候在使用malloc和new时,有一种轻度的紧张和惶恐的感觉时,你就具备了这方面的修养了。 对于malloc和free的操作有以下规则:
- 配对使用,有一个malloc,就应该有一个free。(C++中对应为new和delete)
- 尽量在同一层上使用,不要像上面那种,malloc在函数中,而free在函数外。最好在同一调用层上使用这两个函数。
- malloc分配的内存一定要初始化。free后的指针一定要设置为NULL。 注:虽然现在的操作系统(如:UNIX和Win2k/NT)都有进程内存跟踪机制,也就是如果你有没有释放的内存,操作系统会帮你释放。但操作系统依然不会释放你程序中所有产生了Memory Leak的内存,所以,最好还是你自己来做这个工作。(有的时候不知不觉就出现Memory Leak了,而且在几百万行的代码中找无异于海底捞针,Rational有一个工具叫Purify,可能很好的帮你检查程序中的Memory Leak) carol 发表于 04/04/12 22:04 引用Trackback(0) | 编辑 评论 感觉两者也没有什么优劣之分,相反使用stack 的静态数组更安全好理解。 以后慢慢体会吧。 carol ( carol.blogbus.com ) 发表于 04/04/12 22:11 char pstr[100];会使esp(假设是X86)拨动,这是编译完了生成的代码,运行时发生的(所以我觉得前面说的stack是静态分配有点瞎掰),malloc会从堆上按算法查找一段可用空间返回,差别肯定是有di。嵌入式上在函数里用太大的数据结构,比如数组比较危险,容易造成堆栈溢出,在有保护机制的系统上有可能进一步引起异常 zhou ( zhouxiaohu.blogbus.com ) 发表于 04/04/13 20:51 这么说,如果分配大的数据的话,还是用 malloc 比较好咯 可是这两个都是一次性分配了固定的大小,我希望在数据量超过分配空间的时候,增加分配的空间,有没有比较简单的方法? 哎,看到内存之类的,就知道我有多菜了,,, carol ( carol.blogbus.com ) 发表于 04/04/13 21:13 堆栈中的空间是临时的,函数返回就没了,堆中的才一直都有,这个也要考虑 zhou ( zhouxiaohu.blogbus.com ) 发表于 04/04/14 12:49 嗯~ 我在论坛上也问了下相关的问题,想干脆搞搞清楚 http://www.loveunix.net/index.php?showtopic=26154 也不知道是越搞越清楚还是越来越糊涂了,呵呵~ @@ carol ( carol.blogbus.com ) 发表于 04/04/14 12:57 其实简单跟一下汇编代码就很清楚啦;) zhou ( zhouxiaohu.blogbus.com ) 发表于 04/04/14 21:43 “所以哪怕是程序退出时,也不释放。”只能说是函数退出时不释放。你这里用“程序”不严谨呀。如果进程终止,所有的内存都会释放,如此而已。 wangrujun ( ) 发表于 04/10/19 14:48 :-) 惭愧,这篇文章不是我写的,只是拿来做学习之用的。 carol ( carol.blogbus.com ) 发表于 04/10/19 22:41 发表评论 最后更新 这几天和接下来要做的事情 水王聚会贴 loveunix 征集好的blog方案 什么是google的pagerank 不是好消息 loveunix 开放通告 没有 loveunix 的日子怎么过 loveunix 之 开也心痛,关也心痛 时间流啊流 在绝望中寻求希望