在学习C程序设计语言时,会遇到两个很相似的术语:堆内存和栈内存。这
两个术语虽然只有一字之差,但是所表达的意义还是有差别的,堆内存和栈内存的区别可以用如下的比喻来看出:使用堆内存就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且
自由度
大。使用栈内存就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是
自由度
小。操作系统中所说的堆内存和栈内存,在操作上有上述的特点,这里的堆内存实际上指的就是(满足堆内存性质的)
优先队列
的一种
数据结构
,第1个元素有最高的
优先权
;栈内存实际上就是满足先进后出的性质的数学或
数据结构
。
我们掌握堆内存的权柄就是返回的
指针
,一旦丢掉了指针,便无法在我们视野内释放它。这便是
内存泄露
。而如果在函数中申请一个
数组
,在函数体外调用使用这块堆内存,结果将无法预测。 我们知道在c/c++ 中定义的
数组
大小必需要事先定义好,他们通常是分配在静态内存空间或者是在栈内存空间内的,但是在实际工作中,我们有时候却需要动态的为数组分配大小,这时就要用到堆
内存分配
的概念。在堆
内存分配
时首先应该知道操作系统有一个记录空闲内存
地址
的
链表
,当系统收到程序的申请时,会
遍历
该
链表
,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。堆内存是向高
地址
扩展的
数据结构
,是不连续的内存区域。这是由于系统是用
链表
来存储的空闲
内存地址
的,自然是不连续的,而链表的
遍历
方向是由低地址向高地址。堆内存的大小受限于
计算机系统
中有效的
虚拟内存
。由此可见,堆内存获得的空间比较灵活,也比较大。堆内存是由new分配的内存,一般速度比较慢,而且容易产生
内存碎片
,不过用起来最方便.另外,在
WINDOWS
下,最好的方式是用
VirtualAlloc
分配内存,它直接在进程的
地址空间
中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。
动态分配堆内存
原型: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’
p=(int*)malloc(sizeof(int));
使用malloc函数分配内存时,返回值要经过类型转换才可赋予一个
指针变量
。该函数如分配内存成功,则返回其始
地址
,否则返回NULL。头文件为#include<stdlib.h>。
p=new int;//申请分配一个int型内存空间
p=new int(10);//申请一个int型空间存放10
q=new int[10];//申请分配10个int型的内存空间
new分配内存时不需要类型转换。用new申请的空间必须要用delete释放。而且
指针
值不能改变。形式有:delete
指针变量
名(可释放一个内存单元)、delete[]指针变量名(可释放若干个内存单元)。
#include"iostream"
using namespace std;
main()
{
int array_size;//元素个数
int *array;//用于动态开辟
数组
的
指针变量
cin>>array_size;
array=(int*)malloc(array_size*sizeof(int));/*利用malloc在堆内存中开辟内存空间,它的大小是元素的个数乘以该
数据类型
的长度 */
for(int i=0;i<array_size;i++)
array[i]=i;//输入
数组
for( i=0;i<array_size;i++)
cout<<array[i]<<",";//以逗号间距输出
数组
cout<<endl;//换行
free(array);//利用free释放动态开辟的堆内存空间
cin.get();//按
任意键
结束
return 1;//返回值
}//VC6.0通过 网页格式符 请不要直接复制粘贴本段编译
这里要特别注意个地方就是:array=(int*)malloc(array_size*sizeof(int));malloc()的函数原形本身是void*malloc(size_tsize),由于动态分配的空间计算机并不知道是用来做什么的所以是无类型的,但你要把它用在动态的整形
数组
上的时候就要显式的转换成int*了。
例2:
//malloc.c
#include "iostream"
using namespace std;
main()
{
char *p;
p=(char*)malloc(100*sizeof(char));
if(p)
printf("Memory Allocated at:%x \n",p);
else
printf("Not Enough Memory Available! \n");
free(p);
getchar();//按任意键结束
return 0;
}//VC6.0通过 网页格式符 请不要直接复制粘贴本段编译