Stack的三种含义(数据结构、调用栈、内存区域)

转载 2013年12月02日 22:44:57
原文出处: 阮一峰(@ruanyf)

学习编程的时候,经常会看到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,即某些内存空间不再被使用了,却因为种种原因,没有被系统回收。

栈(stack )数据结构

1、一直说给大伙说说栈,一直没空,fk! 2、栈(stack ),中文名字不错,是的,就叫栈(念zhan),大声再跟我念一遍,栈(zhan) 3、术语不多说了,简单说下栈的概念 ...
  • cadi2011
  • cadi2011
  • 2016年09月15日 22:23
  • 643

java数据结构与算法之栈(Stack)设计与实现

【版权申明】转载请注明出处(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53362993 出自【zejia...
  • javazejian
  • javazejian
  • 2016年11月28日 12:27
  • 9068

【数据结构】使用栈Stack解决迷宫问题

我们看下面这个迷宫----方阵(也可以是矩阵):650) this.width=650;" src="http://s5.51cto.com/wyfs02/M01/7E/E9/wKiom1cMngag...
  • hanjing_1995
  • hanjing_1995
  • 2016年05月30日 17:18
  • 565

Java数据结构----栈(Stack)源码分析和个人简单实现

栈单链表实现:没有长度限制,并且出栈和入栈速度都很快 public class LinkedListStack { private LinkedList linkedList = new L...
  • oChangWen
  • oChangWen
  • 2016年02月17日 23:29
  • 2705

Go语言实现堆栈(Stack)

package main //Stack //author:Xiong Chuan Liang //date:2015-1-30 import ( "fmt" "github.com/xcl...
  • xcltapestry
  • xcltapestry
  • 2015年01月30日 23:14
  • 1326

堆内存(Heap)和栈内存(Stack)详解

原文地址:http://blog.csdn.net/abcjennifer/article/details/39780819 堆:顺序随意  栈:先进后出  堆和栈的...
  • Meta_Cpp
  • Meta_Cpp
  • 2015年01月09日 14:02
  • 2511

Linux C 数据结构——栈

栈是限制在一段进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素称为“空栈”。特点:先进后出(FILO)。 栈顶即top,这里top有...
  • zqixiao_09
  • zqixiao_09
  • 2015年12月28日 11:54
  • 828

使用python实现数据结构 -- Stack(栈)

栈是一种先进后出的数据结构,在计算机中应用广泛,比如函数的调用就是一个入栈出栈的过程,本文介绍使用python实现一个简单栈的过程。栈的调用过程以及内部数据变化如下: stack.py的定义如下: ...
  • sjhuangx
  • sjhuangx
  • 2016年10月29日 21:44
  • 1227

STL常用容器总结——stack栈

原文 栈中的数据是先进后出(FILO),栈只有一个出口,添加和移除元素都只能在栈顶操作。在STL中,栈是以别的容器作为底部结构,修改接口使其符合栈的特性。默认情况下,栈使用deque作为其底层数据结构...
  • sinat_30071459
  • sinat_30071459
  • 2016年04月14日 09:13
  • 1622

堆(heap)和栈(stack)有什么区别??

堆栈存放用户自己用malloc分配的空间,用free来释放;由用户自己管理,而栈存放函数的局部变量,由编译器来负责分配和回收管理,速度快,但容量有限, 简单的可以理解为:  heap:是由ma...
  • ly0303521
  • ly0303521
  • 2015年04月09日 19:40
  • 1661
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Stack的三种含义(数据结构、调用栈、内存区域)
举报原因:
原因补充:

(最多只允许输入30个字)