对堆和栈的主要的区别由以下几点:
1、管理方式不同;
2、空间大小不同;
3、能否产生碎片不同;
4、生长方向不同;
5、分配方式不同;
6、分配效率不同;
管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
空间大小:一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改:
打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit。
注意:reserve最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。
碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。
生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。
栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。
无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生以想不到的结果,就算是在你的程序运行过程中,没有发生上面的问题,你还是要小心,说不定什么时候就崩掉,那时候debug可是相当困难的:)
对了,还有一件事,如果有人把堆栈合起来说,那它的意思是栈,可不是堆,呵呵,清楚了?
全局变量和静态全局变量的区别
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。
Static
1. 静态变量,分配在静态存储区,在数据段中。函数退出之后,变量值不变。
2. 作用域,全局的静态变量、静态函数只能在本文件中使用。(不同于一般全局变量)
局部的静态变量同函数的局部变量
结构体和联合体的区别:
结构体是根据所有元素所占的内存空间的总和来为其分配存储空间
联合体是根据占内存空间最大的那个元素来为其分配存储空间
分享到:
相关推荐
总结起来,局部变量和全局变量主要关乎作用域,栈和堆关注内存分配方式,静态和全局则涉及变量的生命周期和可见性。理解这些概念对于编写高效、无错的代码至关重要。在实际编程中,合理地使用这些特性,可以优化内存...
- **全局变量**与**静态全局变量**的主要区别在于后者的作用范围受到限制。 - **局部变量**与**静态局部变量**的主要区别在于后者在整个程序运行期间都存在。 - **面向对象设计中的static**关键字用于定义类的静态...
根据给定的文件信息,我们将深入探讨全局变量、局部变量、静态全局变量及静态局部变量之间的区别,以及`static`关键字在面向过程与面向对象编程中的不同应用。 ### 面向过程设计中的`static` #### 全局变量 全局...
局部变量与全局变量区别、栈、堆和静态存储区的区别 变量是编程语言中最基本的概念之一,它们可以存储不同的数据类型,并在程序中发挥着重要的作用。在 C++ 中,变量根据定义位置的不同,具有不同的作用域,可以...
在A中定义有全局变量X(或类的静态成员变量),则在动态库B中访问的X,与可执行程序C中访问的X是同一个变量还是两个不同的变量? 答案:是两个不同的变量。 2. 工程中包含动态库A,动态库B,可执行程序C。C依赖于A和...
变量类型和内存管理 变量类型是编程语言中非常重要的一个概念,...我们可以看到,全局变量、静态变量、局部变量和堆区中分配的变量都是程序中常用的变量类型,它们之间的区别和联系都是程序员需要了解的重要知识点。
#### 五、静态变量与非静态变量的区别 **非静态变量**: - 在函数体内部定义的局部变量是非静态的,每次函数调用都会重新创建并赋初值。 - 全局变量默认是非静态的,可以在整个程序中访问。 **静态变量**: - 在...
全局变量、局部变量、静态全局变量、静态局部变量这四种变量类型,各自拥有不同的作用域和生命周期,它们之间的区别对于编写高效、可维护的代码至关重要。 ### 全局变量(Global Variable) 全局变量是在所有函数...
在MFC(Microsoft Foundation Classes)框架中,全局变量和函数的使用与标准C++有所不同,因为MFC工程通常由多个文件组成,需要一种方法来在这些文件之间共享数据和功能。这里将介绍两种在MFC工程中定义全局变量和...
全局变量、局部变量、静态变量三者的区别。
### 全局变量、静态全局变量、静态局部变量与局部变量的区别 #### 一、概述 在编程领域,根据变量的作用域以及存储位置的不同,我们可以将变量大致分为四类:全局变量、静态全局变量、静态局部变量以及局部变量。这...
在iOS开发中,Block、局部变量、全局变量和静态变量(`static`)是编程中常见的概念,它们各自有自己的特点和用途,同时在特定情况下,它们之间也存在一定的联系。让我们详细探讨一下这些知识点。 首先,Block是...
它们根据其定义的位置和特性,可以分为几种不同的类型:局部变量、全局变量、局部静态变量和全局静态变量。这些变量各有其特点和作用域,理解它们之间的区别对于编写高效且无误的C++代码至关重要。 1. 局部变量...
在WPF中,我们可能会遇到需要将控件与这样的全局状态关联的情况,这时绑定到静态变量就变得很有用。 在WPF中,数据绑定是通过`{Binding}`标记扩展或代码-behind来实现的。绑定到静态变量的步骤如下: 1. **定义...
在C++编程中,"静态"一词有多种含义,主要涉及到静态全局变量、静态数据成员和静态成员函数。这些特性在程序设计中扮演着重要角色,尤其在数据结构和算法实现时。以下是对这些概念的详细解释: 1. 静态全局变量: ...
本文涵盖了C语言面试题大汇总之华为面试题,涉及到局部变量、全局变量、extern关键字、for循环、while循环、静态变量、静态函数、内存分配、typedef和struct等知识点,对于C语言学习和面试有重要参考价值。
其中,全局变量和静态变量是两种常见的存储类型,它们在内存的存储位置、初始化和作用域方面存在一些区别。 首先,我们来了解一下C程序的内存布局。一个典型的C程序可以被划分为几个不同的部分,包括正文段、初始化...
全局区(静态区)是存储全局变量和静态变量的存储区。全局区的内容在程序编译时就已经确定,程序运行时不能修改。全局区的空间大小是有限的,默认是 2M。 结论 堆和栈是 C 语言中两个基本的存储区,它们对程序的...
4. 局部静态变量适用于需要在函数调用之间保持状态的场景,它限制了变量的作用范围在函数内部,保证了数据的安全性和封装性,避免了全局变量可能带来的潜在风险。 相对于局部静态变量,全局静态变量指的是在函数...
标题中的“WPF绑定静态变量的示例代码(二)加上IValueConverter”指出了一个具体的编程任务:在WPF应用中,我们需要将静态变量与UI元素绑定,并且利用IValueConverter来处理数据转换,以便于控件能够正确地反映出...