王朝百科
分享
 
 
 

堆内存

王朝百科·作者佚名  2010-05-13  
宽屏版  字体: |||超大  

堆内存是区别于栈区、全局数据区和代码区的另一个内存区域。堆允许程序在运行时动态地申请某个大小的内存空间。

堆内存和栈内存在学习C程序设计语言时,会遇到两个很相似的术语:堆内存和栈内存。这两个术语虽然只有一字之差,但是所表达的意义还是有差别的,堆内存和栈内存的区别可以用如下的比喻来看出:使用堆内存就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。使用栈内存就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。操作系统中所说的堆内存和栈内存,在操作上有上述的特点,这里的堆内存实际上指的就是(满足堆内存性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈内存实际上就是满足先进后出的性质的数学或数据结构。

===================================================

Heap and Stack

Heap就是保存在执行时才能确定大小的变量;

Stack就是保存在编译是就能确定大小的变量;

int main(void){

int size; //编译时就可以确认其大小为4字节,所以保存于Stack;

cin >> size;

function(size);

return 0;

}

void function(int i){

int array[i]; //执行时,根据输入的值才可以确定其大小,所以保存于Heap;

}

分配在标准C语言上,使用malloc等内存分配函数获取内存即是从堆中分配内存,而在一个函数体中例如定义一个数组之类的操作是从栈中分配内存。从堆中分配的内存需要程序员手动释放,如果不释放,而系统内存管理器又不自动回收这些堆内存的话(实现这一项功能的系统很少),那就一直被占用。如果一直申请堆内存,而不释放,内存会越来越少,很明显的结果是系统变慢或者申请不到新的堆内存。而过度的申请堆内存(可以试试在函数中申请一个1G的数组!),会导致堆被压爆,结果是灾难性的。

我们掌握堆内存的权柄就是返回的指针,一旦丢掉了指针,便无法在我们视野内释放它。这便是内存泄露。而如果在函数中申请一个数组,在函数体外调用使用这块堆内存,结果将无法预测。我们知道在c/c++ 中定义的数组大小必需要事先定义好,他们通常是分配在静态内存空间或者是在栈内存空间内的,但是在实际工作中,我们有时候却需要动态的为数组分配大小,这时就要用到堆内存分配的概念。在堆内存分配时首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。堆内存是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆内存的大小受限于计算机系统中有效的虚拟内存。由此可见,堆内存获得的空间比较灵活,也比较大。堆内存是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,它直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

重要函数获得堆内存:malloc()

原型:externvoid*malloc(unsignedintnum_bytes);

功能:分配长度为num_bytes字节的内存块

说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。

malloc的语法是:指针名=(数据类型*)malloc(长度),(数据类型*)表示指针.

释放堆内存:Delete()

原型:Delete(varS:String;Index,Count:Integer);

功能:Delete()删除字符串S中从第Index个字符开始的Count个字符。若Index超出了S的长度,则不执行删除的操作。若Index Count超出了S的长度,则删除从Index到S末尾的字符。若Index或Count出现负数,则不执行删除的操作。

举例:

VarS:String='1234567890';执行Delete(S,1,3)后,S=‘4567890’;执行Delete(S,9,8888)后,S='12345678'执行Delete(S,99,2)后,S=‘1234567890’;执行Delete(S,-1,3)后,S=‘1234567890’

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如何用java替换看不见的字符比如零宽空格​十六进制U+200B
 干货   2023-09-10
网页字号不能单数吗,网页字体大小为什么一般都是偶数
 干货   2023-09-06
java.lang.ArrayIndexOutOfBoundsException: 4096
 干货   2023-09-06
Noto Sans CJK SC字体下载地址
 干货   2023-08-30
window.navigator和navigator的区别是什么?
 干货   2023-08-23
js获取referer、useragent、浏览器语言
 干货   2023-08-23
oscache遇到404时会不会缓存?
 干货   2023-08-23
linux下用rm -rf *删除大量文件太慢怎么解决?
 干货   2023-08-08
刀郎新歌破世界纪录!
 娱乐   2023-08-01
js实现放大缩小页面
 干货   2023-07-31
生成式人工智能服务管理暂行办法
 百态   2023-07-31
英语学习:过去完成时The Past Perfect Tense举例说明
 干货   2023-07-31
Mysql常用sql命令语句整理
 干货   2023-07-30
科学家复活了46000年前的虫子
 探索   2023-07-29
英语学习:过去进行时The Past Continuous Tense举例说明
 干货   2023-07-28
meta name="applicable-device"告知页面适合哪种终端设备:PC端、移动端还是自适应
 干货   2023-07-28
只用css如何实现打字机特效?
 百态   2023-07-15
css怎么实现上下滚动
 干货   2023-06-28
canvas怎么画一个三角形?
 干货   2023-06-28
canvas怎么画一个椭圆形?
 干货   2023-06-28
canvas怎么画一个圆形?
 干货   2023-06-28
canvas怎么画一个正方形?
 干货   2023-06-28
中国河南省郑州市金水区蜘蛛爬虫ip大全
 干货   2023-06-22
javascript简易动态时间代码
 干货   2023-06-20
感谢员工的付出和激励的话怎么说?
 干货   2023-06-18
 
>>返回首页<<
 
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有