首页 > 编程知识 正文

数据结构中栈的应用,堆和栈存储的是什么数据

时间:2023-05-05 00:03:03 阅读:31198 作者:3022

内存中的堆和堆栈使用堆和堆栈的概念,对于内存中(操作系统)的堆和堆栈以及数据结构中的堆和堆栈,解决问题不多。 这次,突然想起了这个问题,所以在这里简单整理总结一下。 如果有错误的话,请向读者指出。

堆栈

堆栈是由系统自动分配和回收的内存。 例如,如果在main函数中依次调用两个全局函数1、2,并编写简单的c程序,使堆栈顺序与main函数的堆栈-调用的函数1的堆栈-调用的函数2的外堆栈顺序相反

堆栈区域位于内存的高地址,从最高内存地址扩展到低地址。 也就是说,对于Push压栈,堆栈顶部指针由最高内存地址向下移动组成

堆栈访问先进后出(FILO)结构。把数据压入栈时用push; 从堆栈中取出数据时,用pop取出。 随着数据被按入或弹出,堆栈将增长或减少。 最新的推式堆栈项目可能位于“堆栈顶部”。 当项目从堆栈中出来时,我们得到的是位于堆栈顶部的那个。 也就是说,是最新推入的人。

在x86体系中,堆栈顶层由堆栈指针寄存器ESP标记。 这是一个32位寄存器,其中包含推入堆栈顶的最后一项的内存地址。 正因为有了那个,我们才能随时操作必要的项目。 需要注意的是栈顶是朝着地内存方向增长的。

在ESP:堆栈指针寄存器(extended stack pointer )的存储器中,始终存储有指向系统堆栈最上面的堆栈帧的堆栈的指针

EBP:基地址指针寄存器(extended base pointer )始终将指针放在内存中,指向系统堆栈顶部堆栈的底部。

在WINDOWS上,堆栈大小为2m (有时也称为1m,但这是编译时确定的常量),如果申请的空间超过了堆栈的剩馀空间,则呈现overflow。 因此,能从栈获得的空间较小

堆空间是向上增长的内存空间,用于分配程序员申请

操作系统具有记录空闲内存地址的链表。 当然,也可以使用位图等其他方法,但这里假设您使用链表。 (如果系统收到程序申请,您将使用(首次自适应) FirstFit算法遍历此链表,查找第一个空间大于所申请空间的堆。)。 然后,从空闲节点的链表中删除此节点,并将此节点的空间分配传递给程序。 此外,大多数系统将在此内存空间的第一个地址中记录此次分配的大小。 这样可以确保代码中的delete语句正确释放此内存空间。 找到的堆节点大小不一定与申请的大小匹配,因此多余的部分将自动重新定位到可用链表中。 也就是说,堆将在申请后做后续工作,出现申请效率问题。

两者分别存储什么以及原因堆栈:是需要编译器时分配、不需要时自动清除的变量的存储区域。 中的变量通常是局部变量、函数参数等。

虽然可以看到堆栈具有ESP寄存器管理,并且从底部开始“自动化”,但堆栈似乎没有额外的内容来帮助管理。

此外,堆栈的大小需要一定的限制。 堆栈的增加将扩展到低地址。 如图所示,如果堆栈持续增加,则很可能与**.bss段**发生冲突。 这是超乎想象的,系统会发出错误并退出程序。

堆栈应该被认为是短期存储数据的位置,堆栈中存在的数据项没有名称,只是跟随后进先出操作。

堆栈常用于在寄存器紧张的情况下临时存储数据,是安全的。

寄存器变空后,可以从堆栈中取出该数据用于寄存器。这种临时存放数据的特性,使得它经常用来存储局部变量,函数参数,上下文环境等。

堆栈是机器系统提供的数据结构,计算机在底层支持堆栈。 分配专用寄存器以存储堆栈的地址,并对堆栈堆栈执行专用指令。 这将导致栈的效率比较高

相反,堆栈更强调堆栈需要控制。 常见的是我们手动申请,手动释放。 因此,可以分配更大的空间,但开销也更多。 于是,我

堆在程序运行过程中来自动态分配,其最大特性为动态性。 堆是在new上分配的内存块,不管理他们的释放编译器,而是由我们的APP应用程序控制。 通常,一个new支持delete。 如果程序员没有被释放,程序结束后,操作系统将自动回收。

其他存储(3)静态存储:所有静态对象、全局对象都分配给静态存储。

(4)常数存储)这是一个比较特殊的存储,他们中存储有常数,不允许修改。 所有常量字符串都存储在静态存储中,并返回常量字符串的起始地址。

示例代码

int a=0; 全局初始化区域char

*p1; 全局未初始化区 int 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);堆 } 栈和堆的比较 项目栈堆申请效率效率高,由系统分配,程序员无法控制效率低,程序员通过new分配,速度较慢,容易产生内部碎片申请大小最大容量一般由系统预先设定,例如2M堆获得的空间较大,较灵活。向高地址扩展,不连续的内存区域(例如用链表存储空闲内存地址)存储内容在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。存取效率char s1[] = "运行时赋值";
放入栈中,是运行时赋值char *s2 = "编译时确定";放入堆中,编译时就确定。(堆中是存储对象的,而在栈中是存放引用)深入阅读

参考资料:内存中的堆和栈到底是什么

数据结构中的堆和栈 栈

一种先进后出的数据结构,栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:

堆中某个结点的值总是不大于或不小于其父结点的值;堆总是一棵完全二叉树。

完全二叉树:若设二叉树的深度为k,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k 层所有的结点都连续集中在最左边,这就是完全二叉树。 (即未满的层只能是最后一层,且节点均连续集中在最左边)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。