堆变量和栈变量

合集下载

嵌入式-c语言变量生命周期详解

嵌入式-c语言变量生命周期详解

c语言变量生命周期详解1、变量的生命周期1.1、研究变量生命周期的意义变量的声明周期的指的就是变量何时诞生何时消亡。

诞生:运行时在内存中分配变量空间。

消亡:内存回收变量空间。

单独理解生命周期是没有意义的,要将其与其它东西结合起来,才会有意义,搞清楚变量生命周期的问题,有助于理解变量的行为特征。

1.2、栈变量的生命周期(1)局部变量空间(自动变量)开辟于栈中,生命周期是临时的,变量空间代码运行时开辟,运行结束后就释放。

譬如一个函数内定义的局部变量,在这个函数每一次被调用时都会创建一次,然后使用,最后在函数返回的时候消亡,而且每一次创建局部变量给变量所分配的内存地址都是不相同的。

思考:一个函数内的局部变量有效期为多久?答:因为函数内的局部变量在函数运行结束时就释放了,局部变量的有效期==函数额有效期。

1.3、堆变量的生命周期堆内存空间是客观存在的,是由操作系统维护的,程序只是去申请使用然后释放而已。

堆变量也有了自己的生命周期,就是:从malloc申请时诞生,然后使用,直到free时消亡,因此开辟于堆内存的变量在malloc之后和free之前不能被访问。

1.4、数据段、bss段变量的生命周期我们知道全局变量空间开辟于数据段或者bss段中,因此全局变量的生命周期是永久的。

永久的意思就是,从程序开始运行到终止时消亡都会一直存在。

全局变量所占用的内存是不能被程序自己释放的,所以程序如果申请了过多的全局变量会导致这个程序一直占用大量内存。

许多同学觉得在写程序时,使用malloc申请内存,还要去使用free释放内存,感觉很麻烦,因此大量的去使用全局变量,这样的话会导致程序大量的内存被占据。

在linux内核中就大量使用malloc/free目的就是为了避免内存被大量占用。

如需要获取更多学习视频资源欢迎加入397164505朱老师物技术交流群学习讨论。

1.5、代码段、只读段的生命周期程序执行的代码值得就是是函数,它的生命周期是永久的。

单片机C语言 必知的数据存储与程序编写知识 附单片机应用编程知识介绍

单片机C语言 必知的数据存储与程序编写知识 附单片机应用编程知识介绍

一、五大内存分区内存分成5个区,它们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

1、栈区(StaCk):FIFo就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。

里面的变量通常是局部变量、函数参数等。

2、堆区(heap):就是那些由new分配的内存块,它们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。

如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

3、自由存储区:就是那些由malloc等分配的内存块,它和堆是十分相似的,不过它是用free 来结束自己的生命。

4、全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

5、常量存储区:这是一块比较特殊的存储区,它们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)code/data/stack内存主要分为代码段,数据段和堆栈。

代码段放程序代码,属于只读内存。

数据段存放全局变量,静态变量,常量等,堆里存放自己malloc或new出来的变量,其他变量就存放在栈里,堆栈之间空间是有浮动的。

数据段的内存会到程序执行完才释放。

调用函数先找到函数的入口地址,然后计算给函数的形参和临时变量在栈里分配空间,拷贝实参的副本传给形参,然后进行压栈操作,函数执行完再进行弹栈操作。

字符常量一般放在数据段,而且相同的字符常量只会存一份。

二、C语言程序的存储区域1、由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。

编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。

2、C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。

堆与栈,静态变量和全局变量的区别

堆与栈,静态变量和全局变量的区别

堆与栈,静态变量和全局变量的区别堆与栈,静态变量和全局变量的区别对和栈的主要的区别由以下几点: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函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。

优化代码的常用方法和策略

优化代码的常用方法和策略

优化代码的常用方法和策略优化代码是编程中非常重要的一项技能,通过优化代码可以提高程序的执行效率和性能。

下面将介绍一些常用的优化代码的方法和策略。

1. 减少循环次数:- 避免不必要的循环,例如可以通过更简单的算法或逻辑来减少循环次数。

- 尽量避免嵌套循环,可以通过将一些内层循环提取到外层循环中来减少循环次数。

2. 使用更高效的数据结构和算法:- 选择合适的数据结构,例如使用散列表(哈希表)可以加快查找操作的速度。

- 尽量使用高效的算法,例如使用快速排序算法替代冒泡排序算法。

3. 减少内存分配:- 避免频繁的内存分配和释放,可以通过使用对象池或缓存来减少内存分配次数。

- 尽量使用栈变量代替堆变量,因为栈变量的分配和释放速度更快。

4. 避免过多的函数调用:- 函数调用会引入额外的开销,尤其是对于频繁调用的函数。

可以通过将一些短小的函数内联展开,减少函数调用的开销。

5. 使用延迟计算:- 避免在不必要的情况下进行计算,可以通过延迟计算的方式来避免重复计算或者不需要的计算。

6. 使用并发编程:- 对于可以并行执行的任务,可以使用并发编程来提高程序的执行效率。

- 可以使用多线程或多进程来同时处理多个任务,充分利用多核处理器的性能。

7. 进行代码剖析和性能测试:- 可以使用工具来分析代码的性能瓶颈,并找出需要优化的部分。

- 在进行代码优化之前,首先要了解哪些部分是性能瓶颈,才能有针对性地进行优化。

8. 使用适当的编译器选项:- 在编译代码时,可以使用一些编译器选项来优化代码的生成。

- 例如使用优化选项可以使得编译器能够对代码进行更好的优化。

9. 避免重复计算:- 在代码中避免重复计算相同的结果,可以通过缓存中间结果来避免重复计算。

10. 利用硬件特性:- 可以针对具体的硬件特性进行优化,例如利用SIMD指令集进行向量化计算,提高代码执行的并行度。

通过以上的一些常用的方法和策略,可以对代码进行优化,提高程序的执行效率和性能。

【转】(深入理解计算机系统)bss段,data段、text段、堆(heap)和栈(stack)

【转】(深入理解计算机系统)bss段,data段、text段、堆(heap)和栈(stack)

【转】(深⼊理解计算机系统)bss段,data段、text段、堆(heap)和栈(stack)bss段: bss段(bss segment)通常是指⽤来存放程序中未初始化的全局变量的⼀块内存区域。

bss是英⽂Block Started by Symbol的简称。

bss段属于静态内存分配。

data段: 数据段(data segment)通常是指⽤来存放程序中已初始化的全局变量的⼀块内存区域。

数据段属于静态内存分配。

text段: 代码段(code segment/text segment)通常是指⽤来存放程序执⾏代码的⼀块内存区域。

这部分区域的⼤⼩在程序运⾏前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。

在代码段中,也有可能包含⼀些只读的常数变量,例如字符串常量等。

堆(heap): 堆是⽤于存放进程运⾏中被动态分配的内存段,它的⼤⼩并不固定,可动态扩张或缩减。

当进程调⽤malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张); 当利⽤free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。

栈(stack): 栈⼜称堆栈,是⽤户存放程序临时创建的局部变量, 也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。

除此以外,在函数被调⽤时,其参数也会被压⼊发起调⽤的进程栈中,并且待到调⽤结束后,函数的返回值也会被存放回栈中。

由于栈的先进先出(FIFO)特点,所以栈特别⽅便⽤来保存/恢复调⽤现场。

从这个意义上讲,我们可以把堆栈看成⼀个寄存、交换临时数据的内存区。

⼀个程序本质上都是由 bss段、data段、text段三个组成的。

这样的概念,不知道最初来源于哪⾥的规定,但在当前的计算机程序设计中是很重要的⼀个基本概念。

⽽且在嵌⼊式系统的设计中也⾮常重要,牵涉到嵌⼊式系统运⾏时的内存⼤⼩分配,存储单元占⽤空间⼤⼩的问题。

内存中堆栈的划分

内存中堆栈的划分

栈和堆的区别 (转) 终于知道区别了(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中堆和栈的区别(图文解释)

尽管在.NET framework下我们并不需要担心内存管理和垃圾回收(Garbage Collection),但是我们还是应该了解它们,以优化我们的应用程序。

同时,还需要具备一些基础的内存管理工作机制的知识,这样能够有助于解释我们日常程序编写中的变量的行为。

在本文中我将讲解栈和堆的基本知识,变量类型以及为什么一些变量能够按照它们自己的方式工作。

在.NET framework环境下,当我们的代码执行时,内存中尽管在.NET framework下我们并不需要担心内存管理和垃圾回收(Garbage Collection),但是我们还是应该了解它们,以优化我们的应用程序。

同时,还需要具备一些基础的内存管理工作机制的知识,这样能够有助于解释我们日常程序编写中的变量的行为。

在本文中我将讲解栈和堆的基本知识,变量类型以及为什么一些变量能够按照它们自己的方式工作。

在.NET framework环境下,当我们的代码执行时,内存中有两个地方用来存储这些代码。

假如你不曾了解,那就让我来给你介绍栈(Stack)和堆(Heap)。

栈和堆都用来帮助我们运行代码的,它们驻留在机器内存中,且包含所有代码执行所需要的信息。

* 栈vs堆:有什么不同?栈负责保存我们的代码执行(或调用)路径,而堆则负责保存对象(或者说数据,接下来将谈到很多关于堆的问题)的路径。

可以将栈想象成一堆从顶向下堆叠的盒子。

当每调用一次方法时,我们将应用程序中所要发生的事情记录在栈顶的一个盒子中,而我们每次只能够使用栈顶的那个盒子。

当我们栈顶的盒子被使用完之后,或者说方法执行完毕之后,我们将抛开这个盒子然后继续使用栈顶上的新盒子。

堆的工作原理比较相似,但大多数时候堆用作保存信息而非保存执行路径,因此堆能够在任意时间被访问。

与栈相比堆没有任何访问限制,堆就像床上的旧衣服,我们并没有花时间去整理,那是因为可以随时找到一件我们需要的衣服,而栈就像储物柜里堆叠的鞋盒,我们只能从最顶层的盒子开始取,直到发现那只合适的。

Java里的堆(heap)栈(stack)和方法区(method)

Java里的堆(heap)栈(stack)和方法区(method)

Java⾥的堆(heap)栈(stack)和⽅法区(method)基础数据类型直接在栈空间分配,⽅法的形式参数,直接在栈空间分配,当⽅法调⽤完成后从栈空间回收。

引⽤数据类型,需要⽤new来创建,既在栈空间分配⼀个地址空间,⼜在堆空间分配对象的类变量。

⽅法的引⽤参数,在栈空间分配⼀个地址空间,并指向堆空间的对象区,当⽅法调⽤完成后从栈空间回收。

局部变量 new 出来时,在栈空间和堆空间中分配空间,当局部变量⽣命周期结束后,栈空间⽴刻被回收,堆空间区域等待GC回收。

⽅法调⽤时传⼊的 literal 参数,先在栈空间分配,在⽅法调⽤完成后从栈空间分配。

字符串常量在DATA 区域分配,this 在堆空间分配。

数组既在栈空间分配数组名称,⼜在堆空间分配数组实际的⼤⼩!哦对了,补充⼀下static在DATA区域分配。

从Java的这种分配机制来看,堆栈⼜可以这样理解:堆栈(Stack)是操作系统在建⽴某个进程时或者线程(在⽀持多线程的操作系统中是线程)为这个线程建⽴的存储区域,该区域具有先进后出的特性。

每⼀个Java应⽤都唯⼀对应⼀个JVM实例,每⼀个实例唯⼀对应⼀个堆。

应⽤程序在运⾏中所创建的所有类实例或数组都放在这个堆中,并由应⽤所有的线程共享.跟C/C++不同,Java中分配堆内存是⾃动初始化的。

Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引⽤却是在堆栈中分配,也就是说在建⽴⼀个对象时从两个地⽅都分配内存,在堆中分配的内存实际建⽴这个对象,⽽在堆栈中分配的内存只是⼀个指向这个堆对象的指针(引⽤)⽽已。

<⼆>这两天看了⼀下深⼊浅出JVM这本书,推荐给⾼级的java程序员去看,对你了解JAVA的底层和运⾏机制有⽐较⼤的帮助。

废话不想讲了.⼊主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和⽅法区(method)堆区:1.存储的全部是对象,每个对象都包含⼀个与之对应的class的信息。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

全局,静态,new产生的变量都在堆中动态分配的变量在堆中分配局部变量在栈里分配函数中声明的变量在栈中用了new标示符在堆中全局变量和static变量都在全局区程序为栈变量分配动态内存,在程序结束时为栈变量分配的空间将自动释放;而为堆变量分配的空间则不会自动释放,若在程序中没有没有释放堆变量,它将一直占用系统内存。

堆栈是一种执行“后进先出”算法的数据结构。

设想有一个直径不大、一端开口一端封闭的竹筒。

有若干个写有编号的小球,小球的直径比竹筒的直径略小。

现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来。

所以“先进后出”就是这种结构的特点。

堆栈就是这样一种数据结构。

它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中。

有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫做堆栈指示器。

开始放入数据的单元叫做“栈底”。

数据一个一个地存入,这个过程叫做“压栈”。

在压栈的过程中,每有一个数据压入堆栈,就放在和前一个单元相连的后面一个单元中,堆栈指示器中的地址自动加1。

读取这些数据时,按照堆栈指示器中的地址读取数据,堆栈指示器中的地址数自动减 1。

这个过程叫做“弹出pop”。

如此就实现了后进先出的原则。

堆栈是计算机中最常用的一种数据结构,比如函数的调用在计算机中是用堆栈实现的。

堆栈可以用数组存储,也可以用以后会介绍的链表存储。

下面是一个堆栈的结构体定义,包括一个栈顶指针,一个数据项数组。

栈顶指针最开始指向-1,然后存入数据时,栈顶指针加1,取出数据后,栈顶指针减1。

#define MAX_SIZE 100typedef int DATA_TYPE;struct stack{DATA_TYPE data[MAX_SIZE];int top;};在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。

里面的变量通常是局部变量、函数参数等。

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。

如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多.int a;void func(int arg){static int b;int c;void *p;p = (void *)malloc(100);}a在文件中声明是全局变量b虽然在函数内声明,但是静态的,所以也在全局数据区c,p是函数内声明,是栈变量arg是参数,是栈变量p指向的空间用malloc分配,是堆空间一、预备知识—程序的内存分配一个由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\0在常量区,p3在栈上。

static int c =0;全局(静态)初始化区p1 = (char *)malloc(10);p2 = (char *)malloc(20);分配得来得10和20字节的区域就在堆区。

strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

}二、堆和栈的理论知识2.1申请方式stack:由系统自动分配。

例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间heap:需要程序员自己申请,并指明大小,在c中malloc函数如p1 = (char *)malloc(10);在C++中用new运算符如p2 = (char *)malloc(10);但是注意p1、p2本身是在栈中的。

2.2申请后系统的响应栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。

另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

2.3申请大小的限制栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。

这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS 下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。

因此,能从栈获得的空间较小。

堆:堆是向高地址扩展的数据结构,是不连续的内存区域。

这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。

堆的大小受限于计算机系统中有效的虚拟内存。

由此可见,堆获得的空间比较灵活,也比较大。

2.4申请效率的比较:栈由系统自动分配,速度较快。

但程序员是无法控制的。

堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。

但是速度快,也最灵活2.5堆和栈中的存储内容栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。

注意静态变量是不入栈的。

当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

堆:一般是在堆的头部用一个字节存放堆的大小。

堆中的具体内容有程序员安排。

2.6存取效率的比较char s1[] = "aaaaaaaaaaaaaaa";char *s2 = "bbbbbbbbbbbbbbbbb";aaaaaaaaaaa是在运行时刻赋值的;而bbbbbbbbbbb是在编译时就确定的;但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

比如:#i ncludevoid main(){char a = 1;char c[] = "1234567890";char *p ="1234567890";a = c[1];a = p[1];return;}对应的汇编代码10: a = c[1];00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]0040106A 88 4D FC mov byte ptr [ebp-4],cl11: a = p[1];0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]00401070 8A 42 01 mov al,byte ptr [edx+1]00401073 88 45 FC mov byte ptr [ebp-4],al第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。

?2.7小结:堆和栈的区别可以用如下的比喻来看出:使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

堆和栈的区别主要分:操作系统方面的堆和栈,如上面说的那些,不多说了。

还有就是数据结构方面的堆和栈,这些都是不同的概念。

这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。

虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。

java的栈和堆的区别栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。

与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。

但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

另外,栈数据可以共享,详见第3点。

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。

但缺点是,由于要在运行时动态分配内存,存取速度较慢。

3. Java中的数据类型有两种。

一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。

相关文档
最新文档