首页 > 编程知识 正文

数据结构的堆和内存的堆,数据结构与算法分析java

时间:2023-05-04 23:36:54 阅读:31233 作者:4324

在计算机领域,堆栈是一个不容忽视的概念,我们编写的c语言程序基本上是使用的。 但是,对于大多数初学者来说,堆栈是一个模糊的概念。 堆栈:数据结构,程序运行时存储的位置,这可能是很多初学者的认识。 我这么想是因为和汇编语言的堆栈这个词混淆了。 我身边的编程朋友和在网上看帖子遇到的朋友中,有很多不算堆栈。 所以,我认为有必要和大家分享我对堆栈的看法。 如果有错误的地方,请朋友告诉我吧。 这对大家的学习很有帮助。

数据结构堆栈和堆

首先,你需要通过数据结构知道堆栈。 我们这么叫它,但实际上堆栈是堆和堆栈两种数据结构。

堆和堆栈是数据项按顺序排列的数据结构。

堆栈就像装数据的水桶和箱子

首先,从大家熟悉的堆栈开始吧。 是具有后进先入性的数据结构。 也就是说,之后保管的东西先取,先保管的东西后取。 这就像取出箱子里下面装的东西(放的更快的物体),我们必须先离开压在上面的东西(放的更慢的物体)。

像倒下的树一样堆起来

堆是不同的。 堆是已排序的树数据结构,每个节点都有一个值。 通常,堆的数据结构是指两股堆。 堆的特点是根节点的值最小(或最大),根节点的两个子树也是一个堆。 由于堆的这个特性,经常被用来实现优先队列。 您可以自由访问堆。 这就像在图书馆的书架上拿书一样。 书的配置有顺序,但不需要像堆栈一样先取出所有的书。 书柜这种结构和箱子不同,我们可以直接取出我们想要的书。

内存分配中的堆栈和堆

但是,我想说的重点不是这里。 我想说的堆和堆栈不是数据结构的堆和堆栈。 之所以说数据结构堆和堆栈,是为了区分我稍后想说的堆和堆栈区域。 请注意。

本节介绍c语言程序内存分配中的堆和堆栈。 这里还需要提到内存分配。 各位,请不要认为我很吵。 一般来说,程序存储在Rom或Flash中,运行时必须复制到内存中运行。 内存中存储着各自不同的信息。 请参照下图。

如果内存中堆栈空间相对较高的地址使地址的增加方向向上,则堆栈地址会向下增加。

为堆栈分配局部变量空间,堆空间向上增加,以分配程序员申请的内存空间。

另外,静态区域分配静态变量、全局变量空间; 只读区域分配常数和程序代码空间。 还有其他分区。

看看网络上流行的典型例子:

main.cpp

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

char *p1; 全局未初始化区域

主() )

{

int b; 堆栈

char s[]='abc '; 堆栈

char *p2; 堆栈

char *p3='123456 '; 123456位于常数区,p3位于堆栈上。

静态输入c=0; 全局(静态)初始化区域

p1=(char* ) malloc ) 10; 堆

p2=(char* ) malloc ) 20; 堆

}

0 .申请方式与回收方式不同

不知道是否明白了一点,堆栈和堆栈的第一个区别是申请方法的不同。 堆栈(英文名为stack )由系统自动分配空间。 例如,定义char a。 系统会自动在堆栈中创建空间。 堆(英文名为heap )是程序员根据需要自己申请的空间,就像malloc(10 )一样。 打开10字节的空间。 由于堆栈上的空间是自动分配和自动回收的,因此堆栈上数据的生存周期只有在函数运行期间,运行后才能释放,不能再访问。 只要程序员不释放空间,就可以访问堆上的数据,但缺点是忘记释放会导致内存泄漏。 还有一些其他的区别。 我觉得网上朋友总结的很好,这里介绍一下:

1 .申请后系统的响应

堆栈:只要堆栈的剩馀空间大于申请的空间,系统就会为程序提供内存。 否则,报告异常并告知堆栈溢出。

堆:首先,您必须知道操作系统有一个包含空闲内存地址的链表。 当系统收到程序申请时,它将遍历此链表以查找第一个空间大于申请空间的堆。

然后,从空闲节点的链表中删除该节点,并将该节点的空间分配给程序。 此外,大多数系统都将此次分配的大小记录在此内存空间的第一个地址中。 这样可以确保代码中的delete语句正确释放此内存空间。 此外,由于找到的堆节点的大小不一定等于申请的大小,因此多余的部分会自动重新定位到可用链表中。

也就是说,堆将在申请后做后续工作,出现申请效率问题。

2 .申请效率比较

从第0分和第1分可以看出。

堆栈:由系统自动分配,速度快。 但是程序员控制不了。

堆:由new分配的内存,通常速度较慢,容易出现内存碎片,但最容易使用。

3 .申请大小限制

堆栈:在Windows上,堆栈是扩展到低地址的数据结构,是连续内存的区域。 堆栈顶部的地址和堆栈最大容量是系统预先确定的,在WINDOWS上,堆栈大小为2m ((有时也称为1m,但这是编译时确定的常数) ),申请的空间为star 因此,从堆栈中得到的空间很小。

堆:堆呢

向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

4.堆和栈中的存储内容

由于栈的大小有限,所以用子函数还是有物理意义的,而不仅仅是逻辑意义。

栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。

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

堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

关于存储内容还可以参考这道题。这道题还涉及到局部变量的存活期。

5.存取效率的比较

char s1[] = "aaaaaaaaaaaaaaa";

char *s2 = "bbbbbbbbbbbbbbbbb";

aaaaaaaaaaa是在运行时刻赋值的;放在栈中。

而bbbbbbbbbbb是在编译时就确定的;放在堆中。

但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

比如:

#include

void 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],cl

11: 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

关于堆和栈区别的比喻

堆和栈的区别可以引用一位前辈的比喻来看出:

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。比喻很形象,说的很通俗易懂,不知道你是否有点收获。

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