rust中的堆和栈

栈和堆是数据结构中的重要概念。栈遵循“先进后出”原则,常用于函数调用,而堆用于动态内存分配,适用于大小不确定或生命周期较长的数据。多线程环境下,共享数据必须使用堆,以防止栈溢出。指针可以引用栈上变量,但仅限于当前栈帧。合理利用栈和堆能有效管理内存,避免安全问题。
摘要由CSDN通过智能技术生成
堆和栈定义:

在数据结构中,栈是一种可以实现“先进后出”(或者称为“后进先出”)的存储结构。假设给定栈 S=(a0,a1,…,an-1),则称 a0 为栈底,an-1 为栈顶。进栈则按照 a0,a1,…,an-1 的顺序进行进栈;而出栈的顺序则需要反过来,按照“后存放的先取,先存放的后取”的原则进行,则 an-1 先退出栈,然后 an-2 才能够退出,最后再退出 a0。

在实际编程中,可以通过两种方式来实现:使用数组的形式来实现栈,这种栈也称为静态栈;使用链表的形式来实现栈,这种栈也称为动态栈。

相对于栈的“先进后出”特性,堆则是一种经过排序的树形数据结构,常用来实现优先队列。它是一种使用数组实现的二叉树。

数据放在堆上还是栈上

我们一般希望把数据放在栈上,因为只需要改动栈指针,就可以预留出空间,这样的运行速度会很快,但是我们又要避免把大量数据放在栈上,因为这样会发生堆栈溢出的问题,一旦当前程序的调用栈超出了系统允许的最大栈空间,无法创建新的帧,来运行下一个要执行的函数,就会发生栈溢出,这时程序会被系统终止,产生崩溃信息。
在这个时候我们就会使用堆,一般都会在堆上预留一些空间,我们使用动态大小的内存的时候,只能使用堆。
堆可以存入大小未知或者动态伸缩的数据类型。堆上存储的变量,其生命周期从分配后开始,一直到释放时才结束,因此堆上的变量允许在多个调用栈之间引用。但也导致堆变量的管理非常复杂,手工管理会引发很多内存安全性问题,而自动管理,无论是 GC 还是 ARC,都有性能损耗和其它问题。一句话对比总结就是:栈上存放的数据是静态的,固定大小,固定生命周期;堆上存放的数据是动态的,不固定大小,不固定生命周期。

两个问题
1.如果有一个数据结构需要在多个线程上访问,可以把它放在栈上吗?

不可以。在多线程场景下,每个线程的生命周期是不固定的,无法在编译期知道谁先结束谁后结束,所以你不能把属于某个线程 A 调用栈上的内存共享给线程 B,因为 A 可能先于 B 结束。这时候,只能使用堆内存。这里有个例外,如果结束的顺序是确定的,那么可以共享

2.可以使用指针引用栈上的某个变量吗?如果可以,在什么情况下可以这么做?

可以,在当前函数调用栈中,可以新建变量在栈上开辟,顺便分配一个指针指向它,但是注意,这个指针的生命周期只能在当前栈帧中,不能作为返回值给别人用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值