理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说, ? ?释放工作由程序员控制,容易产生memory leak。
? ?空间大小:一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看 ? ? 堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如, ? ?在VC6下面,默认的栈空间大小是1M。当然,这个值可以修改。
? ? 碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而 ? ? 造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先 ? ? ?进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间 ? ? 弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构。
? ? 生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向; ? ? 对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
? ? 分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配 ? ?和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由malloca ? ? ?函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放, ? ?无需我们手工实现。
? ? 分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专 ? ?门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。 ? ?堆则是C/
C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会 ? ?按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足 ? ? 够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用 ? ? 系统功能去增加程序数据段的内存空间,这样就有机会分 到足够大小的内存,然后进 ? ? 行返回。显然,堆的效率比栈要低得多。
? ? 从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量 ? ?的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切 ? ?换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的 ? ?调用也利用栈去完成,函数调用过程中的参数,返回地址, EBP和局部变量都采用栈 ? ? 的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。
? ? 虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的 ? ? 内存空间,还是用堆好一些。
? ? 无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界 ? ?的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生以想不到的结果。
?
4.new/delete与malloc/free比较
从
C++角度上说,使用new分配堆空间可以调用类的构造函数,而malloc()函数仅仅是一个函数调用,它不会调用构造函数,它所接受的参数是一个unsigned long类型。同样,delete在释放堆空间之前会调用析构函数,而free函数则不会。
复制代码
?1 class Time{
?2 public:
?3 Time(int,int,int,string);
?4 ~Time(){
?5 cout<<"call Time’s destructor by:"<
?6 }
?7 private:
?8 int hour;
?9 int min;
10 int sec;
11 string name;
12 };
13 Time::Time(int h,int m,int s,string n){
14 hour=h;
15 min=m;
16 sec=s;
17 name=n;
18 cout<<"call Time’s constructor by:"<
19 }
20 int main(){
21 Time *t1;
22 t1=(Time*)malloc(sizeof(Time));
23 free(t1);
24 Time *t2;
25 t2=new Time(0,0,0,"t2");
26 delete t2;?
27 }
复制代码
变量的属性:数据类型、存储类型、作用域、存储期。
?
1、数据类型:就是我们熟悉的int、char、long等,没什么说的;
?
2、存储类型:auto、static、register、extern四种;
?
3、作用域:是指程序中可以使用该变量的区域;
?
4、存储期:是指变量在内存中的存储期限。
?
存储类型:在下面作用域介绍中有说明。
?
作用域:有局部变量和全局变量
?
局部变量:
?
自动变量(动态局部变量,即:函数内定义的,未用static声明静态的局部变量,离开函数,值就消失)
?
静态局部变量:(函数内定义的,用static声明静态的局部变量,离开函数时,值保留)
?
寄存器变量:(频繁使用的变量,放在cpu寄存器中,C++中没必要,因为这就像内置函数一样,怎么处理编译器说的算,离开函数,值就消失)形参(参数传递时,更具情况定义为自动变量或者寄存器变量)
?
全局变量:
?
外部变量(外函数外面定义的变量,其他文件可以通过extern声明后使用,程序结束时消失)
?
静态外部变量(其他文件不可以使用,程序结束时消失)
?
存储期:动态存储和静态存储
?
动态存储:
?
自动变量(本函数有效)
?
寄存器变量(本函数有效)
?
形参(本函数有效)
?
静态存储:
?
静态局部变量(本函数有效)
?
静态全局变量(本文件有效)
?
外部变量(其他文件可以引用)
?
此外还有常量的存储,动态申请的空间(new,malloc)等,上面已经详细介绍。