堆和栈的区别
堆和栈的区别是什么?

堆和栈的区别是什么?⾸先,讨论的堆和栈指的是内存中的“堆区”和“栈区”,OC语⾔是C语⾔的超集,所以先了解C语⾔的内存模型的内存管理会有很⼤的帮助。
C 语⾔的内存模型分为5个区:栈区、堆区、静态区、常量区、代码区。
每个区存储的内容如下:1、栈区:存放函数的参数值、局部变量等,由编译器⾃动分配和释放,通常在函数执⾏完后就释放了,其操作⽅式类似于数据结构中的栈。
栈内存分配运算内置于CPU的指令集,效率很⾼,但是分配的内存量有限,⽐如iOS中栈区的⼤⼩是2M。
2、堆区:就是通过new、malloc、realloc分配的内存块,编译器不会负责它们的释放⼯作,需要⽤程序去释放。
分配⽅式类似于数据结构中的链表。
在iOS开发中所说的“内存泄漏”说的就是堆区的内存。
3、静态区:全局变量和静态变量(在iOS中就是⽤static修饰的局部变量或全局变量)的存储是放在⼀块的,初始化的全局变量和静态变量在⼀块区域,未初始化的全局变量和未初始化的静态变量在相邻的另⼀块区域。
程序结束后,由系统释放。
4、常量区:常量存储在这⾥,不允许修改。
5、代码区:存放函数体的⼆进制代码。
堆和栈的区别:1、堆空间的内存是动态分配的,⼀般存放对象,并且需要⼿动释放内存。
当然,iOS引⼊了ARC(⾃动引⽤计数管理技术)之后,程序员就不需要⽤代码管理对象的内存了,之前MRC(⼿动管理内存)的时候,程序员需要⼿动release对象。
另外,ARC只是⼀种中间层的技术,虽然在ARC模式下,程序员不需要像之前那么⿇烦管理内存,但是需要遵循ARC技术的规范操作,⽐如使⽤属性限定符weak、strong、assigen等。
因此,如果程序员没有按ARC的规则并合理的使⽤这些属性限定符的话,同样是会造成内存泄漏的。
2、栈空间的内存是由系统⾃动分配,⼀般存放局部变量,⽐如对象的地址等值,不需要程序员对这块内存进⾏管理,⽐如,函数中的局部变量的作⽤范围(⽣命周期)就是在调完这个函数之后就结束了。
堆、栈的概念与理解

1、从数据结构层次理解,栈是一种先进后出的线性表,只要符合先进后出的原则的线性表都是栈。至于采用的存储方式(实现方式)是顺序存储(顺序栈)还是链式存储(链式栈)是没有关系的。堆则是二叉树的一种,有最大堆最小堆,排序算法中有常用的堆排序。
2、从系统层次理解,栈是系统为运行的程序分配的先进后出的存储区域。在学习bootloader时知道,在上电后初始化阶段要为各个工作模式下分配堆 栈,这里的堆栈实际上就是指stack,堆栈的说法只是因为历史的原因。在执行函数时,函数内部局部变量的存储单元可以在栈上创建(针对CISC架构而 言,RISC架构下,局部变量的存储单元是在寄存器上创建),函数执行结束时这些存储单元自动被释放。堆是系统管理的可以被程序利用的全局存储空间,动态 内存分配就是从堆上分配。
什么是堆什么是栈
一 英文名称
堆和栈是C/C++编程中经常遇到的两个基本概念。先看一下它们的英文表示:
堆――heap
栈――stack
二 从数据结构和系统两个层次理解
在具体的C/C++编程框架中,这两个概念并不是并行的。深入到汇编级进行研究就会发现,栈是机器系统提供的数据结构,而堆是由C/C++函数库提供的。这两个概念可以从数据结构和系统两个层次去理解:
具体地说,现在计算机(串行执行机制),都直接在代码层次支持栈这种数据结构。这体现在,有专门的寄存器指向栈所在的地址,有专门的机器指令完成数据入栈 出栈的操作。比如ARM指令中的stmfd和ldmfd。因为栈内存分配运算内置于处理器的指令集中,所以效率很高,但是支持的数据有限,一般是整数、指 针、浮点数等系统直接支持的数据类型,并不直接支持其他的数据结构。在CISC中,对子程序的调用就是利用栈来完成的。C/C++中的自动变量也是直接利 用栈的例子,这就是为什么当函数返回时,该函数的自动变量失效的原因(因为栈恢复了调用前的状态)。在RISC下,这些都是通过寄存器来完成的。这些留待 第二部分总结中详细阐述。
内存中堆栈的划分

栈和堆的区别 (转) 终于知道区别了(2007-09-12 08:50:49)转载标签:IT/科技一个由 c/C++ 编译的程序占用的内存分为以下几个部分:1 、栈区( stack )—由编译器自动分配释放,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。
2 、堆区( heap )—一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收。
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3 、全局区(静态区)( static )—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
程序结束后由有系统释放。
4 、文字常量区—常量字符串就是放在这里的。
程序结束后由系统释放。
5 、程序代码区—存放函数体的二进制代码。
例子程序:这是一个前辈写的,非常详细//main.cppint a = 0; //全局初始化区char *p1; //全局未初始化区main(){int b; 栈char s[] = "abc"; //栈char *p2; //栈char *p3 = "123456"; //123456在常量区,p3在栈上。
static int c =0; //全局(静态)初始化区p1 = (char *)malloc(10);p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); //123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}栈:在 Windows 下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。
这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS 下,栈的大小是 2M (也有的说是 1M ,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示 overflow 。
.net中堆和栈的区别(图文解释)

尽管在.NET framework下我们并不需要担心内存管理和垃圾回收(Garbage Collection),但是我们还是应该了解它们,以优化我们的应用程序。
同时,还需要具备一些基础的内存管理工作机制的知识,这样能够有助于解释我们日常程序编写中的变量的行为。
在本文中我将讲解栈和堆的基本知识,变量类型以及为什么一些变量能够按照它们自己的方式工作。
在.NET framework环境下,当我们的代码执行时,内存中尽管在.NET framework下我们并不需要担心内存管理和垃圾回收(Garbage Collection),但是我们还是应该了解它们,以优化我们的应用程序。
同时,还需要具备一些基础的内存管理工作机制的知识,这样能够有助于解释我们日常程序编写中的变量的行为。
在本文中我将讲解栈和堆的基本知识,变量类型以及为什么一些变量能够按照它们自己的方式工作。
在.NET framework环境下,当我们的代码执行时,内存中有两个地方用来存储这些代码。
假如你不曾了解,那就让我来给你介绍栈(Stack)和堆(Heap)。
栈和堆都用来帮助我们运行代码的,它们驻留在机器内存中,且包含所有代码执行所需要的信息。
* 栈vs堆:有什么不同?栈负责保存我们的代码执行(或调用)路径,而堆则负责保存对象(或者说数据,接下来将谈到很多关于堆的问题)的路径。
可以将栈想象成一堆从顶向下堆叠的盒子。
当每调用一次方法时,我们将应用程序中所要发生的事情记录在栈顶的一个盒子中,而我们每次只能够使用栈顶的那个盒子。
当我们栈顶的盒子被使用完之后,或者说方法执行完毕之后,我们将抛开这个盒子然后继续使用栈顶上的新盒子。
堆的工作原理比较相似,但大多数时候堆用作保存信息而非保存执行路径,因此堆能够在任意时间被访问。
与栈相比堆没有任何访问限制,堆就像床上的旧衣服,我们并没有花时间去整理,那是因为可以随时找到一件我们需要的衣服,而栈就像储物柜里堆叠的鞋盒,我们只能从最顶层的盒子开始取,直到发现那只合适的。
heap与stack的区别

heap与stack的区别java 的内存分为两类,⼀类是栈内存,⼀类是堆内存。
栈内存是指程序进⼊⼀个⽅法时,
会为这个⽅法单独分配⼀块私属存储空间,⽤于存储这个⽅法内部的局部变量,当这个⽅法
结束时,分配给这个⽅法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作⽤不同的内存,⼀般⽤于存放不放在当前⽅法栈中的那些数据,例如,使⽤ new
创建的对象都放在堆⾥,所以,它不会随⽅法的结束⽽消失。
⽅法中的局部变量使⽤ final
修饰后,放在堆中,⽽不是栈中。
区别:
1.heap是堆,stack是栈。
2.stack的空间由操作系统⾃动分配和释放,heap的空间是⼿动申请和释放的,heap常⽤new关键字来分配。
3.stack空间有限,heap的空间是很⼤的⾃由区。
在中,
若只是声明⼀个对象,则先在栈内存中为其分配地址空间,
若再new⼀下,实例化它,则在堆内存中为其分配地址。
4.举例:
数据类型变量名;这样定义的东西在栈区。
如:Object a =null; 只在栈内存中分配空间
new 数据类型();或者malloc(长度); 这样定义的东西就在堆区
如:Object b =new Object(); 则在堆内存中分配空间。
队列,栈,堆栈,数组,链表特点与区别

队列,栈,堆栈,数组,链表特点与区别1. 队列可以看成是有2个口的集合一个口叫队头一个叫队尾,只能在对头进行删除操作,在队尾做插入。
根据这样的操作。
队列特点是先进先出2.堆栈可以看成是有1个口的集合,这个口叫栈顶。
插入和删除操作只能在栈顶操作。
根据这样的操作。
堆栈的特点是是后进先出.3.链表是一种存储方式,它可以在非连续的内存空间里面存储一个集合的元素。
4.和它对应的是数组,数组要在连续的空间里存储集合的元素队列、栈是线性数据结构的典型代表,而数组、链表是常用的两种数据存储结构;队列和栈均可以用数组或链表的存储方式实现它的功能数组与链表:数组属于顺序存储中,由于每个元素的存储位置都可以通过简单计算得到,所以访问元素的时间都相同(直接访问数组下标);链表属于数据的链接存储,由于每个元素的存储位置是保存在它的前驱或后继结点中的,所以只有当访问到其前驱结点或后继结点后才能够按指针访问到自己,访问任一元素的时间与该元素结点在链接存储中的位置有关。
链表和数组是常用的两种数据存储结构,都能用来保存特定类型的数据。
1.占用的内存空间链表存放的内存空间可以是连续的,也可以是不连续的,数组则是连续的一段内存空间。
一般情况下存放相同多的数据数组占用较小的内存,而链表还需要存放其前驱和后继的空间。
2.长度的可变性链表的长度是按实际需要可以伸缩的,而数组的长度是在定义时要给定的,如果存放的数据个数超过了数组的初始大小,则会出现溢出现象。
3.对数据的访问链表方便数据的移动而访问数据比较麻烦;数组访问数据很快捷而移动数据比较麻烦。
链表和数组的差异决定了它们的不同使用场景,如果需要很多对数据的访问,则适合使用数组;如果需要对数据进行很多移位操作,则设和使用链表。
堆和栈有什么区别:1. 栈具有数据结构中栈的特点,后进先出,所有存放在它里面的数据都是生命周期很明确(当然要求它不能存放太久,占有的空间确定而且占用空间小),能够快速反应的!所有在Java中它存放的是8个基本数据类型和引用变量的,用完就马上销毁2.堆可以理解它就是个一个可大可小,任你分配的听话的内存操作单元;因此它的特点就是动态的分配内存,适合存放大的数据量!比如一个对象的所有信息,虽然它的引用指向栈中的某个引用变量;所有Java中堆是存放new 出来的对象的。
堆的意思是什么

堆”和“栈”是独立的概念平常说的“堆栈”实际上是两个概念:“堆”和“栈”。
在英文中,堆是heap,栈是stack,不知道什么时候,什么原因,在中文里,这两个不同的概念硬是被搞在一起了,所以,围绕这个混合词所发生的误解和争执这几年就没有断过。
“栈”一般是由硬件(CPU)实现的,CPU用栈来保存调用子程序(函数)时的返回地址,高级语言有时也用它作为局部变量的存储空间。
“堆”是个实实在在的软件概念,使用与否完全由编程者“显示地(explicitly)”决定,如malloc。
程序经过编译连接生成执行程序后,堆和栈的起始地址就已经确定了(具体说,是通过“连接程序”),在一个具有反向增长的栈的CPU上,数据空间可表示如下:低->|-----------------||全局量(所有已初始化量.data,||未初始化量.bss )|堆起始->|-----------------||堆向高地址增长||||||自由空间||||||栈向低地址增长|高栈起始->|-----------------|在内存中,“堆”和“栈”共用全部的自由空间,只不过各自的起始地址和增长方向不同,它们之间并没有一个固定的界限,如果在运行时,“堆”和“栈”增长到发生了相互覆盖时,称为“栈堆冲突”,系统肯定垮台。
由于开销方面的原因,各种编译在实现中都没有考虑解决这个问题,只有靠设计者自己解决,比如增加内存等。
=========================================================== ======说明(128为例)硬堆栈:即SP,通常汇编中讲的所谓堆栈(用于PC指针等压栈),一般设置从片内RAM的顶部0X10FF开始向下生长,基本上64个足够足够了软件堆栈:C编译器自动分配的堆栈,在硬堆栈和全局变量之间的空间,也是向下生长,一般用于局部变量。
比如一个子程序定义一个局部变量A[256],那么此空间即在软堆栈中,假设当前软堆栈用到0X800,分派A[256]后,软堆栈用到0X700,A[0]地址为0X700,A[1]地址为0X701 ……,当然如果局部变量较少,用寄存器就可以了,用不着软堆栈了。
网龙笔试题及标准答案

一.题型:问答五题,程序两题,选择10来题二.题目1.堆和栈的区别与联系(C/C++的内容,不是数据结构的内容)1、栈区(stack)由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
注意它与数据结构中的堆是两回事。
区别:1.管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生内存溢出。
2. 空间大小:堆内存几乎是没有什么限制。
栈一般都是有一定的空间大小。
3. 碎片问题:对于堆来讲,频繁的new/delete会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。
对于栈来讲,则不会存在这个问题。
4. 分配方式:堆都是动态分配的,没有静态分配的堆。
栈有2种分配方式:静态分配和动态分配。
5.分配效率:栈的效率比较高。
堆的效率比栈要低得多。
见:hi.baidu.com/sige_online/blog/item/f06097ecb006bb3f2797918b.html2.重载和覆盖的区别与联系重载是指不同的函数使用相同的函数名,但函数的参数个数或类型不通。
调用的使用根据函数的参数来区别不同的函数。
覆盖是指派生类中重新对基类的虚函数重新实现。
即函数名和参数都一样,只是函数的实现体不一样。
3.什么是多重继承,好处及缺点多重继承指的是一个类别可以同时从多于一个父类继承行为与特征的功能。
优点:可以使用多重继承编写非常复杂、但很紧凑的代码,如C++ ATL库。
缺点:出现二义性、虚函数、访问权限等问题,容易产生混淆。
4.做过什么项目.遇到什么问题(不写似乎没事)自己想吧,根据自己情况写5.不用第三个变量交换两个int型的值(必须用C实现)int a= 2,b= 3;a=a+b;b=a-b;a=a-b;6.链表删除操作此处实现删除链表中的第二个元素。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
堆和栈的区别
4.2 容易被搞晕的--堆和栈
由于"堆"和"栈"这两个概念是看不见摸不着的东西,让很多程序员都整不明白是怎么回事,其实这两个概念也没有什么好研究的,因为堆和栈程序员根本没有办法控制其具体内容。
我们只需要了解一点,栈与堆都是Java用来在内存中存放数据的地方就行了。
然后再弄清楚这两个概念分别对应这程序开发的什么操作,以及堆和栈的区别即可。
4.2.1 堆--用new建立,垃圾自动回收负责回收
1、堆是一个"运行时"数据区,类实例化的对象就是从堆上去分配空间的;
2、在堆上分配空间是通过"new"等指令建立的;
3、Java针对堆的操作和C++的区别就是,Java不需要在空间不用的时候来显式的释放;
4、Java的堆是由Java的垃圾回收机制来负责处理的,堆是动态分配内存大小,垃圾收集器可以自动回收不再使用的内存空间。
5、但缺点是,因为在运行时动态分配内存,所以内存的存取速度较慢。
例如:
String str = new String("abc");
就是在堆上开辟的空间来存放String的对象。
4.2.2 栈--存放基本数据类型,速度快
1、栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄;
2、栈的存取速度比堆要快;
3、栈数据可以共享;
4、栈的数据大小与生存期必须是确定的,缺乏灵活性。
例如:
int a = 3;
就是在堆上开辟的空间来存放String的对象。
4.2.3 何谓栈的"数据共享"
栈其中一个特性就是"数据共享",那么什么是"数据共享"呢?
我们这里面所说的数据共享,并不是由程序员来控制的,而是JVM来控制的,指的是是系统自动处理的方式。
比如定义两个变量:
int a = 5;
int b = 5;
这两个变量所指向的栈上的空间地址是同一个,这就是所谓的"数据共享"。
它的工作方式是这样的:
JVM处理int a = 5,首先在栈上创建一个变量为a的引用,然后去查找栈上是否还有5这个值,如果没有找到,那么就将5存放进来,然后将a指向5。
接着处理int b = 5,在创建完b的引用后,因为在栈中已经有5这个值,便将b直接指向5。
于是,就出现了a与b同时指向5的内存地址的情况。
4.2.4 实例化对象的两种方法
对于String这个类来说它可以用两种方法进行建立:
String s = new String("asdf");
和
String s = "asdf";
用这两个形式创建的对象是不同的,第一种是用new()来创建对象的,它是在堆上开辟空间,每调用一次都会在堆上创建一个新的对象。
而第二种的创建方法则是先在栈上创建一个String类的对象引用,然后再去查找栈中有没有存放"asdf",如果没有,则将"asdf"存放进栈,并让str指向"asdf",如果已经有"asdf" 则
直接把str指向"abc"。
我们在比较两个String是否相等时,一定是用"equals()"方法,而当测试两个包装类的引用是否指向同一个对象时,我们应该用"= ="。
因此,我们可以通过"= ="判断是否相等来验证栈上面的数据共享的问题。
例1:
String s1 = "asdf";
String s2 = "asdf";
System.out.println(s1==s2);
该程序的运行结果是,"true",那么这说明"s1"和"s2"都是指向同一个对象的。
例2:
String s1 =new String ("asdf");
String s2 =new String ("asdf");
System.out.println(s1==s2);
该程序的运行结果是,"false",这说明用new的方式是生成的对象,每个对象都指向不同的地方。