首页 > 其他分享 >笔记整理--C语言--Stack的三种含义 - 博客 - 伯乐在线——转载

笔记整理--C语言--Stack的三种含义 - 博客 - 伯乐在线——转载

时间:2023-08-18 14:44:14浏览次数:49  
标签:cls1 调用 -- 含义 Stack 存放 heap C语言 stack

【转载】:原文 http://www.ruanyifeng.com/blog/2013/11/stack.html

Stack的三种含义 - 博客 - 伯乐在线 - 转载

Stack的三种含义

学习编程的时候,经常会看到stack这个词,它的中文名字叫做”栈”。

理解这个概念,对于理解程序的运行至关重要。容易混淆的是,这个词其实有三种含义,适用于不同的场合,必须加以区分。

含义一:数据结构

stack的第一种含义是一组数据的存放方式,特点为LIFO,即后进先出(Last in, first out)。

bg2013112901

在这种数据结构中,数据像积木那样一层层堆起来,后面加入的数据就放在最上层。使用的时候,最上层的数据第一个被用掉,这就叫做”后进先出”。

与这种结构配套的,是一些特定的方法,主要为下面这些。

- push:在最顶层加入数据。 - pop:返回并移除最顶层的数据。 - top:返回最顶层数据的值,但不移除它。 - isempty:返回一个布尔值,表示当前stack是否为空栈。

含义二:代码运行方式

stack的第二种含义是“调用栈”(call stack),表示函数或子例程像堆积木一样存放,以实现层层调用。

下面以一段Java代码为例(来源)。

class Student{
    int age;
    String name;

    public Student(int Age, String Name)
    {
        this.age = Age;
        setName(Name);
    }
    public void setName(String Name)
    {
        this.name = Name;
    }
}

public class Main{
    public static void main(String[] args) {
            Student s;
            s = new Student(23,"Jonh");
    }
}

上面这段代码运行的时候,首先调用main方法,里面需要生成一个Student的实例,于是又调用Student构造函数。在构造函数中,又调用到setName方法。

bg2013112902

这三次调用像积木一样堆起来,就叫做”调用栈”。程序运行的时候,总是先完成最上层的调用,然后将它的值返回到下一层调用,直至完成整个调用栈,返回最后的结果。

含义三:内存区域

stack的第三种含义是存放数据的一种内存区域。程序运行的时候,需要内存空间存放数据。一般来说,系统会划分出两种不同的内存空间:一种叫做stack(栈),另一种叫做heap(堆)。

bg2013112903

它们的主要区别是:stack是有结构的,每个区块按照一定次序存放,可以明确知道每个区块的大小;heap是没有结构的,数据可以任意存放。因此,stack的寻址速度要快于heap。

bg2013112904

其他的区别还有,一般来说,每个线程分配一个stack,每个进程分配一个heap,也就是说,stack是线程独占的,heap是线程共用的。此外,stack创建的时候,大小是确定的,数据超过这个大小,就发生stack overflow错误,而heap的大小是不确定的,需要的话可以不断增加。

根据上面这些区别,数据存放的规则是:只要是局部的、占用空间确定的数据,一般都存放在stack里面,否则就放在heap里面。请看下面这段代码(来源)。

public void Method1()
{
    int i=4;

    int y=2;

    class1 cls1 = new class1();
}

上面代码的Method1方法,共包含了三个变量:i, y 和 cls1。其中,i和y的值是整数,内存占用空间是确定的,而且是局部变量,只用在Method1区块之内,不会用于区块之外。cls1也是局部变量,但是类型为指针变量,指向一个对象的实例。指针变量占用的大小是确定的,但是对象实例以目前的信息无法确知所占用的内存空间大小。

这三个变量和一个对象实例在内存中的存放方式如下。

bg2013112905

从上图可以看到,i、y和cls1都存放在stack,因为它们占用内存空间都是确定的,而且本身也属于局部变量。但是,cls1指向的对象实例存放在heap,因为它的大小不确定。作为一条规则可以记住,所有的对象都存放在heap。

接下来的问题是,当Method1方法运行结束,会发生什么事?

回答是整个stack被清空,i、y和cls1这三个变量消失,因为它们是局部变量,区块一旦运行结束,就没必要再存在了。而heap之中的那个对象实例继续存在,直到系统的垃圾清理机制(garbage collector)将这块内存回收。因此,一般来说,内存泄漏都发生在heap,即某些内存空间不再被使用了,却因为种种原因,没有被系统回收。

标签:cls1,调用,--,含义,Stack,存放,heap,C语言,stack
From: https://www.cnblogs.com/stlong/p/17637523.html

相关文章

  • Echarts常用参数
    一些以后应该能用到的参数option={title:{//图表的标题配置text:'主标题文本',subtext:'副标题文本',show:true//是否展示标题},tooltip:{//提示框配置trigger:'item',//触发类型,可选值:'item'(数据项触发),'axis'(坐标轴触发),'none'(不触发)axisP......
  • java实现音乐随机播放算法
    importjava.util.*;publicclassRandomDemop{staticRandomrd=newRandom();//获取随机数的工具staticListnList=newArrayList();//保存随机数//获取随机数publicstaticvoidgetRandomNum(){for(inti=1;i<6;i++){nList.add(newInteger(rd.next......
  • 为什么要敏捷开发,敏捷开发有什么好处?
        软件开发方法一直处在不断发展过程中。在诸多方法中,敏捷开发以其能持续满足不断变化的用户需求正在受到越来越多人的重视,从中小项目开始进入大型开发项目,近几年来上升势头明显。那么,敏捷开发有什么好处呢?    在软件工业界,敏捷开发已成为众多高效开发团队的制胜之......
  • Cannot reduce the visibility of the inherited method from Father
    有如下两个类 Father类:publicclassFather{ publicvoidf(){System.out.println("Father.f()");}}  Son类:publicclassSonextendsFather{privatefinalvoidf(){//这里会出现编译错误Cannotreducethevisibilityoftheinheri......
  • 错误org.hibernate.AnnotationException: No identifier specified for entity
    AnnotationExceptionNoidentifierspecifiedforentity错误org.hibernate.AnnotationException:Noidentifierspecifiedforentityorg.hibernate.AnnotationException:Noidentifierspecifiedforentity.报这个异常的原因是因为JavaBean的主键没有注解映射关系,加上对应......
  • 第一家公司的最后一天上班
    2012.6.21号,公司上班的最后一天,今天因为有事,请了半天假,我也不想,可没办法,下午来的时候,这边管事的同事说这边交接完下周就可以不来了,当时还想,之前说想早点走,非是不干的,现在这边招不到人过来交接了,叫走的时候就走吧,其实没什么,本来是打算下周再上两天班的,这又打破计算,得在家里呆一周了,......
  • 使用 OpenCV Python 检测和可视化两个图像之间的差异
    使用OpenCVPython检测和可视化两个图像之间的差异转自:使用OpenCVPython检测和可视化两个图像之间的差异-Glasshost如果您需要比较两个图像并确定它们之间的差异,OpenCVPython提供了一种简单有效的方法来完成此任务。本指南将向您展示如何使用OpenCVPython检测和可视......
  • eclipse调试时鼠标移动到变量上不显示值的问题
    今天同事问一问题,就说在eclipse中调试时,鼠标移动到变量上不显示值,这个原来自己也遇到过,没注意,反正就使用ctrl+shift+i嘛,也可以的,刚查了一下,解决方法如下: Window->Preferences->Java->Editor->Hovers将[VariableValues]选择即可,如果第一个[CombinedHover]已经勾选,则将这个勾去掉......
  • call,apply,bind的区别
    1.三者都可用于改变函数中this指向,但又有细微区别2.三者的语法传参大致相同,第一个参数表示跟谁建立链接,从第二个参数开始传入具体参数值,但其中apply需要用数组进行传入3.call和apply都可直接调用函数,但bind是返回一个新函数......
  • MyEclipse9.0安装jad反编译插件
    1.下载反编译工具jad(下面提供下载)将下载下来的jadstar158.zip解压缩,将jad.exe文件放入jdk安装目录下如:D:\ProgramFiles\Java\jdk1.6.0_20\bin 2.下载eclipse反编译插件net.sf.jadclipse_3.3.0.jar(下面提供下载) 3.将net.sf.jadclipse_3.3.0.jar 放入MyEclipse安装目录下, 如 :安......