Delphi中的堆,栈

来自:http://blog.163.com/liang_liu99/blog/static/884152162009111303756371/

--------------------------------------------------------------------------------------------

Heap:堆,Heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里 
Stack:栈或堆栈,Stack上分配的内存系统自动释放

以下摘自 <<Essential Pascal>>

Delphi 用堆的形式来给对象,字符串,动态数组,分配内存;那些有特殊用途的动态存储空间(用GetMem获取)也是用堆实现的。

Delphi 用栈来存储参数和返回值,本地例程变量等等。对 Windows API 调用也要用到栈。

Windows 应用程序可以保留大量的内存空间以备建栈之用。在 Delphi project 选项的 linker 页里,你可以进行这方面的设置,当然,默认的设置基本上已经可以满足要求了。如果出现了栈满的错误,这常常是因为你的某个函数一直在对自己进行递归调用的缘故,而不是因为栈太小了。

一 堆栈的概念

堆栈(Stack)是一种比较重要的线性数据结构,如果对数据结构知识不是很了解的话,我们可以把它简单的看作一维数组。但是对一维数组进行元素的插入、删除操作时,可以在任何位置进行,而对于栈来说,插入、删除操作是固定在一端进行的,这一端称为栈顶(top),另一端称为栈底(bottom),向栈中插入数据的操作称为压入(Push),从栈中删除数据称为弹出(Pop)。

 

二 堆栈的存储方式

对栈中元素的操作是按后进先出(Last In First Out,简称LIFO)的原则进行的,即最后压入的元素最先弹出。

在栈的操作过程中,有一个永远指向栈顶的栈顶指针,在压入和弹出数据时,栈顶指针向上或向下移动。当栈顶指针为零时(即指向栈底的后面),栈为空栈。如果压入的数据过多超出了栈的最大空间,则发生栈上溢。

在程序设计中,我们可以使用一维数组实现对栈的操作。假设用一维数组s[1..arrmax]表示栈,则对于非空栈,s[1]为最早压入栈的元素,同时设栈顶指针top,则s[top]为最后压入栈的元素。当top=arrmax时栈满,若此时有数据入栈将产生“数组越界”的错误,极为栈上溢,反之当top =0,意为栈空。

 

三 堆栈的存储演示

 

 

有些人可能认为,我们要学习的内容是函数的递归调用知识,与堆栈有什么关系。实际上程序在执行的过程中,为了实现函数的嵌套调用都离不开栈。为什么函数在多层嵌套调用以后程序执行不会混乱?为什么函数被调用以后还能返回到原处继续执行?这都是堆栈的功劳。

8086寄存器(1)

代码段

+-------+<--- CS 
| 指令 |
+-------+
| 指令 |
+-------+<--- IP
| 指令 |
+-------+
| …… | 
+-------+

数据段

+-------+<--- DS 
| 数据 |
+-------+
| 数据 |
+-------+<--- SI (DI)
| 数据 |
+-------+
| …… | 
+-------+

堆栈段

+-------+<--- SS 
| 栈帧 |
+-------+
| 栈帧 |
+-------+<--- BP
| 栈帧 |
+-------+
| …… |<--- SP 
+-------+

汇编是最底层的计算机语言,写汇编程序就是在对内存和寄存器操作。以上描述的代码段、数据段、堆栈段都是指内存中某段区域。当程序编译时,编译器会把程序中的代码分配到不同的内存区域。这时,代码段和数据段在内存中的位置和宽度都已固定好,而堆栈段只有起始位置,没有实际的内容,在运行时根据数据动态伸缩,因此,它是运行时系统很重要的一个部分。存放在内存中的(注意,指令在没有被CPU处理时,只是一串字符)都是数据。

内存有了数据,这时就要用到寄存器。所有的指令运算都要经过CPU中的运算器,而运算器并不知道要处理的数据在哪,因此,寄存器就扮演了数据定位的角色。寄存器也是CPU的一部分,它就专门在内存中找数据,然后告诉运算器做处理。这一过程,有个专门的术语叫“寻址”。

这里并不对所有的寄存器做介绍,只说明一些最常用的。图中用箭头表示的都是寄存器。这些都由CPU指定了特定的功能,不能作其它用途。CS和IP这两个寄存器只负责在代码段寻址,CS定位到了代码段,IP定位到具体的指令。原先说过,在内存中的都是数据,当IP有所指向的时候,数据变成了可以执行的程序,交付运算器执行。CS的地址由系统来指定。IP的控制权不在用户,而是CPU本身。DS和SI、DI负责数据段寻址,数据段是保存全局并赋值的数据的地方。 SI用于读数据,DI用于写数据。DS也是由系统指定,其中的数据读取有专门的寻址方法(见gas初级教程中的寻址一节和其它的实例代码)。SS由系统维护的堆栈段首地址,初始时SP、BP和SS处于同一位置。堆栈是一动态内存区域,它的伸展方向是从高地址向低地址方向延伸。因此,高地址处叫做“栈底”,低地址处叫做“栈顶”。SP是堆栈指针,始终指向栈顶,由它来负责栈的伸缩。在函数调用时,函数中的数据都在堆栈中,BP就用来限制只能读取函数内部的数据。每个函数的调用,都用一个帧框表示,通过不同的帧框来区分不同的函数,BP就在帧框中移动。

还有AX、BX、CX、DX四个通用寄存器,它们在一般情况下可任意使用。但在一些指令中会有特别说明其中的特殊用途(请查看CPU指令手册)。

本人水平有限,因为在学汇编语言时,又不得不了解寄存器的操作。这里只能抛砖引玉,作简单介绍。望各位指点。

时间: 2024-11-07 17:10:31

Delphi中的堆,栈的相关文章

【转载】程序中的堆 栈 可读写数据区 常量区 代码区

一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵. 3.全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块

Java中的堆与栈

一.栈 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用.但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性.栈数据可以共享. 那些数据存放在栈中? 基本数据类型(int, short, long, byte, float, double, boolean, char)的变量存放于栈中. 对象的引用存放于栈中. 栈数据共享具体指什么意思? int a = 3; int b = 3

C语言中的堆与栈20160604

首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件由栈,堆,数据段(由三部分部分组成:只读数据 段,已经初始化读写数据段,未初始化数据段即BBS)和代码段组成,如下图所示: 其中所谓静态,就是一定会存在的而且会永恒存在.不会消失,这样的数据包括常量.常变量(const 变量).静态变 量.全局变量等. 动态的话,就是会变化的了.动态的区域,就是堆和栈.这个栈应该称作 call stack,上面会存放函数的返回地址.

详细介绍Java中的堆和栈

栈与堆都是Java用来在RAM中寄存数据的中央.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运转时数据区,类的对象从中分配空间.这些对象经过new.newarray.anewarray和 multianewarray等指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以静态地分配内存大小,生活期也不用事 先通知编译器,因为它是在运转时静态分配内存的,Java的垃圾搜集器会自动收走这些不再运用的数据.但缺陷是,由于要在运转时静态

C,C++中的堆与栈

堆栈是一种执行“后进先出”算法的数据结构. 设想有一个直径不大.一端开口一端封闭的竹筒.有若干个写有编号的小球,小球的直径比竹筒的直径略小.现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来.所以“先进后出”就是这种结构的特点. 堆栈就是这样一种数据结构.它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中.有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫

数据结构中的堆和栈 与 内存分配中的堆区和栈区 分析

比較全面的总结了诸多版本号,知识无国界.感谢各位的辛勤劳作. 在计算机领域,堆栈是一个不容忽视的概念,我们编写的C/C++语言程序基本上都要用到.但对于非常多的初学着来说,堆栈是一个非常模糊的概念. (1) 数据结构的栈和堆 首先在数据结构上要知道堆栈,虽然我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈. 堆和栈都是一种数据项按序排列的数据结构. 栈就像装数据的桶或箱子 我们先从大家比較熟悉的栈说起吧.它是一种具有后进先出性质的数据结构,也就是说后存放的先取.先存放的后取.这就如同我们要取出

java中的堆和栈

Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用. 堆内存用于存放由new创建的对象和数组以及包装类.在堆中分配的内存,由java虚拟机自动垃圾回收器来管理.在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象

Java中的堆和栈的区别

当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先出(Last In First Out)的顺序的数据结构,这就是java.util.Stack.这种情况下,不免让很多人更加费解前面的问题.事实上,堆和栈都是内存中的一部分,有着不同的作用,而且一个程序需要在这片区域上分配内存.众所周知,所有的Java程序都运行在JVM虚拟机内部,我们这里介绍的自然

java中的堆、栈、常量池

java中的堆.栈.常量池 分类: java2010-01-15 03:03 4248人阅读 评论(5) 收藏 举报 javastring编译器jvm存储equals Java内存分配: 1. 寄存器:我们在程序中无法控制2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中3. 堆:存放用new产生的数据4. 静态域:存放在对象中用static定义的静态成员5. 常量池:存放常量6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间-----------------