栈上创建与堆上创建有何不同,怎样选择?

解决方案 »

  1.   

    自己的一点认识,希望大家指正:函数的参数,以及在函数中,定义的非static类型的变量,在栈上创建,这些变量对应的存储空间随着函数的调用而创建,随着函数的返回而释放。
    每个应用程序对应自己的栈空间,栈是一个管理非常整齐的空间。通过new或类似的函数,如Alloc,GlobalAlloc等,开辟的空间在堆上创建,这些空间不自动释放,必须调用相关的操作。
    因为开辟和释放的顺序是不定的,一次申请的空间又必须是连接的,所以堆会越来越乱。static 类型的变量,分配在代码空间上,随程序的加载出现,不同于以上两者。
      

  2.   

    wangjinwang说的很好,在下也小议一番
    堆和栈的用途:
    1。一般来说,需要自己申请内存空间的情况下使用alloc,new等方法在堆中开辟内存,这些内存不随程序的运行而自动消失,必须由程序员自行删除,堆在VC中还是经常使用的。
    2。除非特别使用到栈的数据结构特性,一般不怎么使用。但是编译器却在运行时大量使用栈,例如函数,在运行中,函数都是以栈的形式运行的,包括形式参数,局部变量等等。
      

  3.   

    补充:堆分配的内存在进程结束之后系统会自行回收。即使你new之后不进行delete,程序关闭后这块内存不会丢失。
      

  4.   

    虽然我们知道了堆和栈的用途,但是栈和堆在内存中在结构是什么样的啊?我知道栈具有先进后出的结构,那堆呢?对采用的是什么样的结构?为什么队的结构适用于存放(管理)使用new,alloc等方法产生的内存空间?
    同样是存放函数调用时的参数(或者说保存断点,以方便函数返回时继续运行什么的),为什么要使用两种不同的的数据结构在实现呢?
      

  5.   

    看大家都说了,那我也来说两句吧。其实这种东西,最好不要问别人,自己慢慢思考直到有一天豁然开朗,如醍醐灌顶的感受能让你一辈子忘不了。得来得太容易,就没有印象了。
    stack和heap是两种不同管理方式的内存。stack的特性我想不需多讲,如上面诸位所说,是一种先进后出的线性表。在程序中,栈是系统管理的,它的主要用途就是传递参数。如果你学过汇编,应该知道子程序之间传递参数一般有寄存器和栈两种,前一种,就是经常能见到的修饰符__fastcall。寄存器传递参数虽然快,但是它有致命的缺点,就是80x86系列CPU的寄存器数量非常少(因为它是CISC体系的CPU,不是RISC体系),如果参数很多,用寄存器传递显然不现实,那么就要用到栈。其实如果只是单纯的函数调用,栈的优点还显示不出来,栈最大的优点显示在函数的嵌套调用和递归调用中。调用函数按照一定的规则,设置栈单元,然后call被调用的函数(至于设置堆栈的规则,有PASCAL规则和C规则之分,__stdcall不是纯的PASCAL规则,__cdecl是指定C规则,具体如果你想知道,我下次再说),因为栈是一种后进先出的线性表,所以最后被调用的函数的参数和局部变量最先出栈,然后是调用该函数的函数……直至最初触发调用动作的函数。正是因为这个特性,我们无须去对函数局部变量的出栈次序进行管理。
      

  6.   

    heap和stack本身没有什么特殊的结构,所谓的各种结构其实都是逻辑上的,物理上,不论多复杂的数据结构,都是一个一个的内存单元,一个一个的字节。heap,是os对空闲内存的组织方式,因为os事先是不知道你需要多大的内存的,所以必须你自己从一大块蛋糕中“挖”一块下来,自己的事情自己负责,当然最后你自己负责把它归还回去。
    这种管理方式比较自由,但是容易造成各种错误。
    正因为stack和heap这种操作和管理上的不同,所以它们不能互相代替。
      

  7.   

    codewarrior(会思考的草),你的解释非常精辟,如果你有时间能否发表一篇文章来详述以下有关C/C++中函数调用、运行时的内存结构方面的细节啊?我们期待着你有这样的举动!多谢了!JerKii
      

  8.   

    恩好的,不过最近没有时间,刚毕业上班啊,杂事贼多。好多东西我比较赞成自己去try。
      

  9.   

    刚毕业就学得这么厉害,不错不错,有前途!
    虽然自己去琢磨会得到更深刻的理解,但是如果有别人的帮助的话就可以少走不少弯路啊?
    我比较喜欢站在巨人的肩膀上提高自己。JerKii
    http://www.cntomorrow.com:3310