计算机程序中的堆和栈的区别,内存中的堆与栈(stack)和栈的区别

前言:我们经常听到一个概念,堆和栈。实际上,数据结构中有两个相同的概念,但这与内存堆栈不同。本文还将说明它们之间的区别,此内。函数完成后,这些内容将被自动销毁。 。它的特点是效率高,但内存大小有限。

(4)堆区域--------由malloc和calloc分配的内存区域,其生命周期由free确定。堆的内存大小由程序员分配,理论上可以占据系统的所有内存。

这四个类别如下:

64b0dfaa78bfdf62608ef4198dba67d6.png

个人喜好,对这四个类别有更好的了解。请注意.bss .data在这里的含义。

摘要:

1. 5函数调用存储在堆栈存储器中后的返回地址

调用该函数时,将使用指向该函数的指针来指向该函数。函数返回时,它将返回到调用位置,该位置是函数调用结束后的返回地址。

此外,返回地址存储在堆栈中。首先调用的函数首先放在堆栈上,然后最后弹出,然后最后调用的函数放在堆栈上,然后首先弹出。

二、关于内存堆栈(内存堆栈)

2. 1堆栈溢出

程序自动将“堆栈”分配并回收给操作系统。它既快速又易于使用,但是不能由程序员控制。但是堆栈空间很小。只要堆栈的剩余空间大于请求的空间,系统就会为程序提供内存。如果要分配的空间大于堆栈内存,分配将失败并提示堆栈溢出错误。

#include int main()

{

int i = 10; //变量i储存在栈区中

const int i2 = 20; //const局部变量也存储在stack

int i3 = 30;

std::cout << &i << " " << &i2 << " " << &i3 << std::endl;

return 0;

}

/*运行结果为:

0x28fedc  0x28fed8 0x28fed4  16进制地址,递减的

*/

注意:const局部变量也存储在堆栈区域中,并且堆栈区域沿地址递减的方向增长。

2. 2堆栈的特征

([1)应用程序大小限制

在Windows下,堆栈是一个扩展到低位地址的数据结构,是内存的连续区域。这句话意味着系统顶部将确定堆栈顶部的地址和堆栈的最大容量。在Windows下,堆栈的大小为2M(有人说是1M,简而言之,这是在编译时确定的常数),如果当请求的空间超过堆栈的剩余空间时,将提示溢出。因此,堆栈中可用的空间较小。

([2) Stack应用程序的效率很高

系统自动分配堆栈,速度更快。但是程序员没有控制权,结束后它将由操作系统释放。

([3)堆栈使用过程

当堆栈处于函数调用中时,

此函数调用结束时,局部变量首先从堆栈中弹出,然后是参数,最后是堆栈顶部的指针指向最初存储的地址,这是存储区中的下一条指令。主要功能,此后程序将继续运行。

三、关于内存堆(内存堆)

3. 1堆溢出

堆是一个扩展到更高地址的数据结构,并且是一个不连续的存储区域。这是因为系统使用链表存储空闲内存地址,这自然是不连续的。链表的遍历方法是从低地址到高地址,并且堆的大小受计算机系统中有效内存的限制。可以看出,堆获得的空间相对灵活,相对较大。

程序员向操作系统申请一块内存。当系统收到该程序的应用程序时,它将遍历记录空闲内存地址的链表,找到第一个空间大于请求空间的堆节点,然后从空闲节点列表中删除该节点。 ,并将节点的空间分配给程序。分配速度慢,地址不连续,并且很容易碎片化。另外,应用程序是由程序员编写的,程序员也必须负责破坏程序,否则会导致内存泄漏。

3. 2堆特征

操作系统具有一个链接列表,该列表记录了可用内存地址。当系统收到程序的应用程序时,它将遍历链接列表以查找其空间大于请求的空间的第一个堆节点,然后从可用空间中选择该节点。从链接列表中删除,然后将节点的空间分配给程序。另外,对于大多数系统而言,此分配的大小将记录在此内存空间的第一个地址,这样代码中的delete语句就可以正确释放此内存空间。另外,由于找到的堆节点的大小可能与应用程序的大小不完全相同,因此系统会自动将多余的部分放入空闲列表中。

([1)应用程序大小限制

堆是一个扩展到更高地址的数据结构,并且是一个不连续的存储区域。这是因为系统使用链表存储自然不连续的空闲内存地址,并且链表的遍历方向是从低地址到高地址。堆的大小受计算机系统中可用物理内存的限制。可以看出,堆获得的空间更加灵活,更大。

([2)堆使用效率

堆是new分配的内存,通常速度较慢并且容易出现内存碎片,但是使用起来最方便。

([3)堆使用的过程

堆:通常,一个字节用于在堆的开头存储堆的大小。堆中的特定内容由程序员安排。

摘要:

堆栈内存:从高地址到低地址,连续,快速,小空间;

堆栈内存:从低地址到高地址,不连续,缓慢且空间大。

可以列为下表:

如何申请

内存大小

使用效率

存储内容

堆栈(堆栈)

自动发布应用程序

高效

堆(堆)

手动申请发布

四、为什么C和C ++在传递数组时传递地址或引用?

从上面的分析中我们可以知道,由于该函数的参数存储在堆栈存储器中,所以如果一个数组比较大,我就传递一个大数组。如果将数组的值复制到形式参数,将不可避免地导致堆栈内存不足,即“堆栈溢出”,因此可以通过仅传递地址值而不传递实际值来避免此问题。 。实际上,诸如Java和C#之类的语言也具有相同的基本原理,这将在后面解释。

摘要:

C语言中函数的参数传递通常分为值传递/指针传递

在C#,Java和C ++中,函数的参数传递通常分为值传递/引用传递

实际上,从内存“堆栈存储器”的角度来看,所有函数参数的传递只有一种形式,即值传递。

因为参数是一个值,所以堆栈中的值将被复制到函数的形式参数中,这当然是值传递,

如果参数是地址或引用,它还将在堆栈区域中复制该地址或将引用传递给函数参数,但是此地址或引用不是真实数据,复制的地址相同或引用的任何人将指向同一条数据,因此我们称其为传递的引用或地址。

简而言之:传递地址或引用只是表面的,本质是“按值传递”。

个人理解,如果伟大的上帝有更好的理解,我希望与大家分享和交流,谢谢。如果您想彻底理解这些概念,可以将几篇文章结合起来阅读,以更好地理解它们。

五、 C#内存管理

有关详细信息,请参阅我的另一篇文章:

在一篇文章中了解C#的堆,栈,值类型,引用类型

C#(CLR)中的内存分配分析

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-fly.com/a/shoujiruanjian/article-373658-1.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值