CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

谁能把堆和栈的概念讲清楚,高分解惑

楼主ppzhao(菜鸟王)2002-12-12 16:53:23 在 C/C++ / C语言 提问

c搞了很长时间了,对这个概念还没有透彻理解  
  汇编里好像堆栈不分的  
  问题点数:100、回复次数:25Top

1 楼geezell(好想学C++的小毛驴)回复于 2002-12-12 17:19:48 得分 10

栈主要主要存放为运行函数的局部变量,函数参数,返回数据,返回地址  
  而堆主要是自由存储区,多用于类对象.Top

2 楼Stephen_Ma(极品飞马)回复于 2002-12-12 17:25:34 得分 10

动态分配在堆中  
  如:int*   pInt   =   new   int(10);  
  下面的定义在栈中  
  int   pInt;Top

3 楼freezingfire(让美梦来得更猛烈些吧)回复于 2002-12-12 17:26:05 得分 0

一般说的堆栈就是栈,英文stack。  
   
  堆则就是堆,英文heap。  
   
  具体的区别,以前有很多大虾将过,搜搜以前的贴子,也许就有收获。Top

4 楼iamxia()回复于 2002-12-12 17:27:35 得分 10

堆:可以是不连续的内存空间,随机访问  
  栈:连续的内存空间,访问是后进先出Top

5 楼dahuzizyd(你就是我心中的女神)回复于 2002-12-12 17:31:31 得分 0

栈,先进先出,只能对栈顶元素操作,既最先进栈的元素最后才能出栈。  
  push(出栈),pop(入栈   );Top

6 楼dancing999(芯片)回复于 2002-12-12 17:36:01 得分 10

看过战斗的电影吗?  
  假如说子弹是存储单元,  
  子弹夹就是栈,后压进去的子弹,先被打出来!  
  子弹箱子就是堆,你取子弹,是随机的在里面取!  
  子弹带就是链,每个子弹就是一个节点!  
  如果还不清楚,找本c/c++描述的数据结构,万事ok!  
  Top

7 楼steedhorse(晨星)回复于 2002-12-12 17:51:09 得分 0

重机枪的子弹是队列(Queue),^_^Top

8 楼steedhorse(晨星)回复于 2002-12-12 17:55:25 得分 10

这都是比较简单的概念,你之所以没理解清楚,我想可能是钻牛角尖了。  
  两外,我个人认为这两个数据结构没有太多的联系,因此没必要放在一起作类比。堆就是堆,栈就是栈,而你同时问这两个概念,是不是因为你觉得他们除了区别,还有一些联系?Top

9 楼lsaturn(土星-站了一晚)回复于 2002-12-12 18:05:13 得分 0

可以说整个内存空间就是一个堆Top

10 楼uniharmony(阿周)回复于 2002-12-12 18:17:28 得分 0

存储分配里的堆和栈与数据结构里的堆和栈是同一种东西么?  
   
  Top

11 楼ppzhao(菜鸟王)回复于 2002-12-12 20:17:32 得分 0

 
  动态分配在堆中  
  如:int*   pInt   =   new   int(10);  
  //同意,明白  
  下面的定义在栈中  
  int   pInt;  
  //是这样的嘛?  
  Top

12 楼ppzhao(菜鸟王)回复于 2002-12-12 20:23:22 得分 0

数据结构中的栈我比较明白  
   
  存储分配的栈,是不是每个运行的程序多有一个,有多大呢?  
  有时栈益出,我能不能把栈扩大一点呢?  
   
  堆是不是还剩多少内存,我多可以用。抢先占用到别的程序没得用了Top

13 楼nanyu(南郁(d2school.com))回复于 2002-12-12 20:55:25 得分 40

哈哈哈,我以为我来晚了。。原来有一点大家还没有讲到,就是二者在内存里位置。。这一点很重要噢,因为你是学汇编的,而学汇编的人学习高级语言的时候,最恨不得的就是一件事:把内存看得清清楚楚。  
  汇编用得少的人,一般不会有这个感受,他们是往上讲的:  
   
  一、关注方向:  
   
        数据结构           咱位还是往下讲:       堆,栈  
            ^                                                                 |  
            |                                                                 V  
          堆,栈。                                                   内存    
   
  二、内存  
      无论是堆或栈,都是内存,二者在物理结构当然是共用一个身子:内存。所以,我们先来看看内存,为了直观,我们假设内存由下而上,内存地址越来越高,并且地址按一个整数的大小:4字节递增,这样可以少写一点数字。  
   
                                  0x00410068     |               |  
                                  0x00410064     |               |  
                                  0x00410060     |               |  
                                        ...             |     ...     |  
                                  0x00120048     |               |  
                                  0x00120044     |               |  
                                  0x00120042     |               |  
  呵呵,这样是不是和汇编书的讲的很像啊?当然,内存地址我是瞎写的。  
   
  三   然后,给它一刀   极其重要的一刀  
        这一刀要把上面的内存拦腰斩下,然后上面就是栈,它的入口在朝上,下面就是堆,它的入口在下(像个向下开的布袋)。然后事实上这一刀却又从来不在曾存在。因为,如果真把一刀定死谁是堆,谁是栈,那么要是堆的空间不够用了,而栈的空间却闲得很,岂不让人笑话IT先哲这智商?所以,这是虚拟的一刀……  
   
        栈>                     0x00410068     |               |  
                                  0x00410064     |               |  
                                  0x00410060     |               |  
      虚拟的一刀>----   -   -   -   -   -   -   -   -   --   -   -   -  
                                  0x00120048     |               |  
                                  0x00120044     |               |  
        堆>                     0x00120042     |               |  
   
  剩下的事情还有很多啦。最直观的方法是开个VC或CB,然后写个带参数的函数  
  ,调试时,看看CPU了。。我就不讲了。。。  
   
  以下是广告时间:  
   
  兄弟们当中有没有是C++入门者?有没有行外想学习编程的。。。最好的编程初学者网校,去年《程序员》,《电脑报》,《电脑爱好者》都向其各自读者推荐过的网站……就是本人的网站啦,报名学员越万名……要交钱的。28元。第二期。欢迎:   http://www.bcbschool.comTop

14 楼zeqxd(莫等闲,白了少年头,空悲切……)回复于 2002-12-12 21:21:08 得分 0

倒楼上的大哥你还真是会在这赚RMB啊。服了U  
  当然更服了U的一番详解,让我也明白了很多东西。谢谢。Top

15 楼ToUpdate(老六)回复于 2002-12-13 04:06:26 得分 0

upTop

16 楼nanyu(南郁(d2school.com))回复于 2002-12-13 06:51:29 得分 0

不好意思,广告时间内我睡着了。。。。噢,有人在表扬我吗?  
   
  四、知其然,知其所以然  
      上面我们知道了堆和栈在内存中“样子”。下面我们要问一句:为什么要一个程序的内存要出堆和栈?难道不能就一整块的内存拿来用,程序中的数据就是在这里头生生死死(分配、释放)不行吗?  
      前面有人说,栈里头数据的特点是:先入后出。我们的这个问题,若是针对这一点,就可以换成“为什么要这么累?为什么要分先入后出和先入先出和随入随出”。统一来个“先入先出”不行吗?这里的入即分配,出,即释放。  
      其实,直觉上最好是“随生随死”。即:这块数据我们需要时,就为这块数据分配内存,而当多们不需要这块数据,就让释放它的内存。。呵呵,说对了,堆里的数据就是这样。这很直观。很像我们生活中样子,先生不一定先死,当然更不一定后死。  
      不过,你注意到了没有,即然是“随生随死”,控制权也就完全掌握在程序员的手里,反过来,责任也就完全落在程序员的手里,你掌管它生,你也就一样要负责它去死。否则,就会有内存泄漏了。这会让程序员很累,并且很危险。万一忘了怎么办?  
      再者,汇编语言里,编译器要做的事很简单,但对于高级语言,编译器所做事就复杂了,它不得不也要产生一些临时数据,这些数据我们程序员根本管不到,所以它们的死,得由编译器负责。  
      因些,需要有一种内存机制,可以合理地实现数据在内存中自生自死的问题。  
      真的有一种机制可以“合理”地实现数据在内存自生自死吗?C#和Java嚷嚷着说,它们说不仅有,而且它们实现了大统一,能让堆和栈里数据都可以该死就死。这就是“内存回收”的意思。其实这是一种以牺牲效率(降低速度和占用内存)换来解决程序员自在的技术,在当初机器还很慢,内存很少的年代产生的C,C++来说,当然不现实。  
      事实是,并没有一种机制可以真正解决数据的自生自死。因为编译器不可能简单地知道你的哪个数据不要了,哪个数据现在还要。你看:  
      假设有个结构:  
      struct   A  
      {  
            struct   B*   pb;  
      }  
      A里有个指针,需要指向B.  
      然后还有个结构:  
      struct   B  
      {  
          struct   A*   pA;    
      }  
      B里有个指针需要指向A。  
       
      现在有段   “生”数据   的代码:  
   
      struct   B   b;  
      struct   A   a;  
     
      也就是说生了两个数据:a和b;   并且,是b先生,a后生。好,如果你是编译器,你说一会让它们死时,应该让谁先死啊?可能无所谓,谁先死都没事,也可能全是地雷,让a先死,结果b里头那个pa正好指的是a,并且它还要用到a呢。。。。  
      在没有完美合理的解决方法的情况下,只好退而求其次,找一种比较合理的方法:那就是“先生后死”。尽管这不大像生活的样子,但毕竟在程序里,一个后面产生的数据可能依赖于前面已有数据,这种情况要比反方向多。  
      编译器就按这种约定而对付你(程序员)扔在栈里数据。它自生需要产生的临时数据(典型的如函数传递的参数),也是这样。程序员如果决定放弃一个数据的夺杀权,就得在逻辑上维护这个数据和其它数据的依赖关系符合“先生后死”的约定。  
      当然,对于堆里的数据,你更得维彼此之间依赖关系。一个程序一大,程序员总是要疲于奔命地看:啊,这个死了,可是那个还要访问这个。。。完了。。又是“访问了非法内存。。。”。再者,对于全局变量,它们也在堆里,可是它们的生死全都由编译器决定,所以我们得特别注意这一点,以前我在这里回答关于全局变量生死的一个问题。看到这里还没睡着的,有兴趣可以找找。  
      事情就是这样子,因为有些数据需要由编译器来实现它们固定的生死次序,所以写编译器的人就决定开一块特殊的内存空间,好实现这一点。最后打个比喻。如果我给你A,B,C三块糖,让你放入口袋,并且要求你一会儿不用看,就直接按C,B,A的次序一一拿出来给我,你会怎么办?如果你只是随手往你的大口袋一扔,估计一会儿你不仅不能实现,还很有可能拿出的是不是糖,而是你的一只臭袜子噢。。。所以你决定单独缝一个口袋,这个口袋糖放下以后会自动叠起来,这不就好实现我们的“先入后出”了吗?栈就是那个口袋。  
   
      好了。把课程全抄到这里,有空大家去我的网站看更多课程。886。  
     
       
  Top

17 楼vcracoon(vcracoon)回复于 2002-12-13 07:58:00 得分 0

不错不错,讲得非常好,我一定去看看Top

18 楼asvaboy1980(蓝boy)回复于 2002-12-13 08:02:43 得分 0

hoho,csdn还真有高手Top

19 楼JoshuaLi()回复于 2002-12-13 13:20:28 得分 0

学习Top

20 楼JoshuaLi()回复于 2002-12-13 13:25:34 得分 0

学习Top

21 楼golinjin(仙剑奇侠)回复于 2002-12-13 13:31:53 得分 0

heheTop

22 楼n5(没啥说的,就喜欢编程!)回复于 2002-12-13 14:01:55 得分 0

c++中,static变量和全局变量放在什么地方?所谓的静态存储区怎么解释?Top

23 楼suacker(星剑)回复于 2002-12-13 14:04:37 得分 10

a   good   questionsTop

24 楼ppzhao(菜鸟王)回复于 2002-12-13 14:08:36 得分 0

nanyu(南郁)   (   )   讲得非常生动明了  
  给分Top

25 楼zhengguoshan(坚持-决不放弃)回复于 2002-12-13 14:11:39 得分 0

一般说的堆栈就是栈,英文stack。  
   
  堆则就是堆,英文heap。  
   
   
  栈是可以自己释放空间..  
  堆不能....  
  Top

相关问题

  • 谁能把static讲清楚?
  • 在线等待,讲清楚就给分???
  • 混淆的概念,望高手解惑!!分不够,加!
  • 解惑!!
  • 谁把setwindowext和setviewext讲清楚,100分就是谁的啦:)
  • 谁能给我讲清楚引用调用的实质??
  • 请大虾解惑!
  • 请高手解惑
  • 解惑的,请进!
  • C++继承解惑?

关键词

  • c++
  • 内存
  • 数据
  • 编译器
  • 程序员
  • 汇编
  • 函数
  • 数据结构
  • 分配
  • 先死

得分解答快速导航

  • 帖主:ppzhao
  • geezell
  • Stephen_Ma
  • iamxia
  • dancing999
  • steedhorse
  • nanyu
  • suacker

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo