请问堆和栈有什么区别?讨论答案,现在开始求慎解

请问堆和栈有什么区别? [re: yuan_weiqi]

 

 

google.com搜索编译原理与实践,看第7章,就会明白大概了



--------------------
做不到的事情就不要说
http://byoneself.yeah.net

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: yuan_weiqi]

 

 

;),它们的名字不同啊 -/


--------------------
吃,吃,吃,我要把linux 吃个精光

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: crazyd]

 

 

有道理,:)


--------------------
做不到的事情就不要说
http://byoneself.yeah.net

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: crazyd]

 

 

嘿嘿,也不一定哦,经常说堆栈堆栈的,尤其10年前的书,stack都翻作堆栈的,现在讲究点了翻作栈了,可见名字没什么区别的,不要误导别人哦:))laugh

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: crazyd]

 

 

原来所谓的高手就是这个样子
难道各位认为自己真的真的觉得自己很清楚堆和栈的区别吗?

文章选项:

[精华] 算了 我来现眼吧 [re: yuan_weiqi]

 

 

反正我在这里被说胡说也不是第一次 我对这个东西的概念一直不是很清楚 但是有一些自己的认识 如果有错大家就尽情板砖我吧~~~ 来吧 让烂西红柿来的更猛烈一些

堆和栈我觉得是数据的2种存储方式

堆好象是说放在data段(还有一个未初始化的段是用的扩展段么?它干嘛用的我不道 莫非是malloc他们用?)的数据 好象在C里用来存储全局变量用吧 还能存别的不道了

栈嘛 自然是堆栈段啦(想叫栈段不过好象不够响亮)那里是先进后出表 因为其特色呢一般来存储局部数据 比如说呢 你函数中使用的局部变量啊 函数之间传递的变量啊 都用栈来做

基本就是这个了 欢迎大家补充和纠正吧 :)



--------------------
家中谁人添饭?
原来正是飞龙在

文章选项:

[精华] Re: 算了 我来现眼吧 [re: teawater]

 

 

>堆好象是说放在data

不是,data段就是用来存放初始化数据的,堆在linux里具体指的是什么,我也不是太确定,可能是malloc整出来的东西吧


--------------------
Jim Zeus

文章选项:

[精华] Re: 算了 我来现眼吧 [re: teawater]

 

 

简单点,就是 使用堆的内存需要用malloc向操作系统申请;全部栈的内存应该是在程序一开始运行就申请好了的,使用栈的内存只需要移动栈顶指针。因为要利用栈保护现场、传递参数、定义局部变量、恢复现场,因此在栈里的变量不能离开作用域而生存。


--------------------
患得患失的光阴是从前的命运
奔向未来的憧憬充满大地

文章选项:

[精华] Re: 算了 我来现眼吧 [re: sdjiangwei]

 

 

那是算data段了吧?
malloc
是对系统调用 brk 的封装 brk的作用就是change data segment size
全局变量也是放在data 那全局变量是否也算 呢?


--------------------
家中谁人添饭?
原来正是飞龙在

编辑者: teawater (03-08-24 17:34)

文章选项:

[精华] Re: 算了 我来现眼吧 [re: teawater]

 

 

静态或者全局(都是全局量)如果初始化在data,未初始化bss
堆和栈一般在一起,不过是位置方向不一样,堆从下面长,栈从上面往下掉。

当然说的都是一般情况,二般的??比如多线程的东东,各个线程一般有自己的栈,一般共享全局堆。

堆,不过是一堆内存,你拿去用罢了,:)



--------------------
渴了喝水,饿了吃饭

文章选项:

[精华] Re: 算了 我来现眼吧 [re: tengel]

 

 

堆和栈一般在一起
怎么在一起?2个段呀 能详细说一下么?


--------------------
家中谁人添饭?
原来正是飞龙在

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: yuan_weiqi]

 

 

(Stack)和堆(Heap)是两个不同层次上的概念。
栈应该是在CPU一级的概念,即栈对CPU是可见的,每一个基本的调度单位(进程或线程)都有自己独立的栈,供上下文切换和局部变量内存空间分配使用。
堆是一个应用层的概念,即堆对CPU是不可见的,它的实现方式有多种,可以由OS实现,也可以由运行库实现,如果你愿意,你也可以在一个栈中来实现一个堆:)。
有的OS的实现了比较简单的堆的调用接口,
C
运行库中的堆则实现了比较复杂的堆的功能来支持动态内存的分配与释放。当然运行库中的堆是使用了OS中的内存访问的系统调用来实现的。
堆栈这个概念很容易混淆,大部分情况下指的是一个栈(Stack)


--------------------
我是一个文学青年,我的第一个作品叫做 hello,world !

文章选项:

[精华] Re: 算了 我来现眼吧 [re: teawater]

 

 

我现在觉得堆是一个语言里的概念,在不同的操作系统里有不同的具体含义。


--------------------
患得患失的光阴是从前的命运
奔向未来的憧憬充满大地

文章选项:

[精华] Re: 算了 我来现眼吧 [re: tengel]

 

 

〉〉堆和栈一般在一起,不过是位置方向不一样,堆从下面长,栈从上面往下掉。

栈的增长方向与CPU有关。CPU决定了栈的增长方向、字节顺序等



--------------------
患得患失的光阴是从前的命运
奔向未来的憧憬充满大地

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: softmaster]

 

 

〉〉你也可以在一个栈中来实现一个堆:)。
我认为,在栈里实现一个堆不大可能,而在堆里实现一个栈倒比较容易


--------------------
患得患失的光阴是从前的命运
奔向未来的憧憬充满大地

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: yuan_weiqi]

 

 

很喜欢你生气的样子,grin
呵呵,不开玩笑了,其实大家有点胡扯,也不是有意,因为堆和栈这2个概念本身就比较混沌,有时候是指两种数据结构,教科书里写的比较清楚(不过说实在的,堆的定义还真有点忘了,shrug);有时候,这2个概念又指两种内存分配的方式,这通常是在操作系统原理里讲。上面这2种情况,原理性概念性比较强,实际中真很少人去仔细想(惭愧ing)。第三种时候,也是我在前面胡扯的,呵呵,这2个概念通常又混在一起,大家都堆栈堆栈的说,时间长了,也分不清了:),这还是和第二种有关,因为大多数OS通常是将heapstack放在一起(或者说比较接近),通常一个在高端,一个在低端,分配内存时,方向是相对的,之间并没有很明确的界限,APUE CHAP7有讲。
另外,印象中,两者还有一个区别就是,stack通常用于函数调用,而heap通常用于进程内局部变量的分配,不过这个印象是很久之前的印象了,不知道对不对。
BTW
,偶不是高手,连所谓的都不是:),不过倒学到一点技巧,这里的高手往往不轻易出手,最好的方法就是刺激他们,嘿嘿

文章选项:

[精华] Re: 请问堆和栈有什么区别? [re: softmaster]

 

 

〉〉栈应该是在CPU一级的概念,即栈对CPU是可见的,

单纯讨论栈的概念,我认为栈只是一种FILO的数据结构。平时用栈这个名称指代进程/线程的工作栈


--------------------
患得患失的光阴是从前的命运
奔向未来的憧憬充满大地

文章选项:

[精华] 我说是一般啊,二般、三般还多得很 [re: sdjiangwei]

 

 

堆栈的位置之类和具体实现非常相关。可以用CPU提供的机制,也可以不用,过分的讨论我觉得意义不大。一般来说(又是一般, ^&^),系统中除了初始化的和未初始化的数据节之外,其它部分都是堆栈(当然代码节也要去了),所以我说在一起。一般如此,当然有兄弟说栈的方向和CPU以及寄存器的标志位相关,那也是二般情况,还有三般呢,某些处理器没有堆栈寄存器,用一个普通的地址寄存器来做,pushpop不过使用mov来实现的。
这是从cpu层面来说的,但是那个编译器会不用CPU的机制呢。
用堆来实现栈当然可以,其实本来也可以这么说,所有的动态内存都是堆,从里面拿出一块来用来肝什么用,是自己的事情。比如某些线程库的实现就是这样


--------------------
渴了喝水,饿了吃饭

文章选项:

[精华] Re: 我说是一般啊,二般、三般还多得很 [re: tengel]

 

 

我觉得堆和栈应该是2个理论概念了 实现起来有多种方式


--------------------
家中谁人添饭?
原来正是飞龙在

文章选项:

[精华] 堆和栈 [re: teawater]

 

 

堆和栈

作者:未知 日期:2003-7-14 来源:CSDN

一般认为在c中分为这几个存储区

1
- 有编译器自动分配释放
2
- 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3
全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块
区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
-
程序结束释放
4
另外还有一个专门放常量的地方。 - 程序结束释放
在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是
在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态
区),在所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内
定义的static表示只在该函数体内有效。另外,函数中的"adgfdf"这样的字符串存放在常量区。
比如:
代码:

int a = 0; //
全局初始化区
char *p1; //
全局未初始化区
main()
{
int b; //

char s[] = "abc"; //

char *p2; //

char *p3 = "123456"; //123456\0
在常量区,p3在栈上。
static int c = 0
//全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//
分配得来得1020字节的区域就在堆区。
strcpy(p1, "123456");
//123456\0
放在常量区,编译器可能会将它与p3所指向的"123456"优化成一块。
}


还有就是函数调用时会在栈上有一系列的保留现场及传递参数的操作。
栈的空间大小有限定,vc的缺省是2M。栈不够用的情况一般是程序中分配了大量数组和递归函数层次太
深。有一点必须知道,当一个函数调用完返回后它会释放该函数中所有的栈空间。栈是由编译器自动管
理的,不用你操心。
堆是动态分配内存的,并且你可以分配使用很大的内存。但是用不好会产生内存泄漏。
并且频繁地mallocfree会产生内存碎片(有点类似磁盘碎片),因为c分配动态内存时是寻找匹配的
内存的。而用栈则不会产生碎片。
在栈上存取数据比通过指针在堆上存取数据快些。
一般大家说的堆栈和栈是一样的,就是栈(stack),而说堆时才是堆heap.
栈是先入后出的,一般是由高地址向低地址生长。
转载的另外一篇:

(heap)和栈(stack)C/C++编程不可避免会碰到的两个基本概念。首先,这两个概念都可以在讲数据
结构的书中找到,他们都是基本的数据结构,虽然栈更为简单一些。
在具体的C/C++编程框架中,这两个概念并不是并行的。对底层机器代码的研究可以揭示,栈是机器系
统提供的数据结构,而堆则是C/C++函数库提供的。
具体地说,现代计算机(串行执行机制),都直接在代码底层支持栈的数据结构。这体现在,有专门的寄
存器指向栈所在的地址,有专门的机器指令完成数据入栈出栈的操作。
这种机制的特点是效率高,支持的数据有限,一般是整数,指针,浮点数等系统直接支持的数据类型,
并不直接支持其他的数据结构。因为栈的这种特点,对栈的使用在程序中是非常频繁的。对子程序的调
用就是直接利用栈完成的。机器的call指令里隐含了把返回地址推入栈,然后跳转至子程序地址的操
作,而子程序中的ret指令则隐含从堆栈中弹出返回地址并跳转之的操作。C/C++中的自动变量是直接利
用栈的例子,这也就是为什么当函数返回时,该函数的自动变量自动失效的原因。

和栈不同,堆的数据结构并不是由系统(无论是机器系统还是操作系统)支持的,而是由函数库提供的。
基本的malloc/realloc/free函数维护了一套内部的堆数据结构。当程序使用这些函数去获得新的内存
空间时,这套函数首先试图从内部堆中寻找可用的内存空间,如果没有可以使用的内存空间,则试图利
用系统调用来动态增加程序数据段的内存大小,新分配得到的空间首先被组织进内部堆中去,然后再以
适当的形式返回给调用者。当程序释放分配的内存空间时,这片内存空间被返回内部堆结构中,可能会
被适当的处理(比如和其他空闲空间合并成更大的空闲空间),以更适合下一次内存分配申请。这套复杂
的分配机制实际上相当于一个内存分配的缓冲池(Cache),使用这套机制有如下若干原因:

1.
系统调用可能不支持任意大小的内存分配。有些系统的系统调用只支持固定大小及其倍数的内存请
(按页分配);这样的话对于大量的小内存分类来说会造成浪费。

2.
系统调用申请内存可能是代价昂贵的。系统调用可能涉及用户态和核心态的转换。

3.
没有管理的内存分配在大量复杂内存的分配释放操作下很容易造成内存碎片。

堆和栈的对比

从以上知识可知,栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而栈是函数库
提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。栈是系统数据结构,对于进
/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。栈空间
分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由
alloca
函数完成。栈的动态分配无需释放(是自动的),也就没有释放函数。为可移植的程序起见,栈的
动态分配操作是不被鼓励的!堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回
系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。

文章选项:

[精华] 讲得很明白 [re: chambers]

 

 

文章选项:

[精华] Re: 堆和栈 [re: chambers]

 

 

对于栈是否在硬件级支持,其实也不全是了,像MIPS架构的CPU在硬件上就不支持栈,没有出栈、压栈指令


--------------------
世上本没有路,走的人多了,便有了路。

文章选项:

[精华] Re: 算了 我来现眼吧 [re: coldwind]

 

 

=========================================
heap
=========================================
In certain programming languages including C and Pas
cal, a heap is an area of pre-reserved computer main storage (memory) that a program process can use to store data in some variable amount that won't be known until the program is running. For example, a program may accept different amounts of input from one or more users for processing and then do the processing on all the input data at once. Having a certain amount of heap storage already obtained from the operating system makes it easier for the process to manage storage and is generally faster than asking the operating system for storage every time it's needed. The process manages its allocated heap by requesting a "chunk" of the heap (called a heap block) when needed, returning the blocks when no longer needed, and doing occasional "garbage collecting," which makes blocks available that are no longer being used and also reorganizes the available space in the heap so that it isn't being wasted in small unused pieces.
The term is apparently inspired by another term, stack. A stack is similar to a heap except that the blocks are taken out of storage in a certain order and returned in the same way. In Pascal, a subheap is a portion of a heap that is treated like a stack.
=========================================
stack
========================================
(1) TCP/IP is frequently referred to as a "stack." This refers to the layers (TCP, IP, and sometimes others) through which all data passes at both client and server ends of a data exchange. A clear picture of layers similar to those of TCP/IP is provided in our description of OSI, the reference model of the layers involved in any network communication.

The term "stack" is sometimes used to include utilities that support the layers of TCP/IP. The Netscape Handbook says (and we quote): "To make a successful connection to the Internet, your PC needs application software such as Netscape plus a TCP/IP stack consisting of TCP/IP software, sockets software (Winsock.dynamic link library), and hardware driver software (packet drivers). Several popular TCP/IP stacks are available for Windows, including shareware stacks."

(2) In programming, a stack is a data area or buffer used for storing requests that need to be handled. The IBM Dictionary of Computing says that a stack is always a push-down list, meaning that as new requests come in, they push down the old ones. Another way of looking at a push-down list - or stack - is that the program always takes its next item to handle from the top of the stack. (This is unlike other arrangements such as "FIFO" or "first-in first-out.")


--------------------
I want to believe.

文章选项:

[精华] Re: 算了 我来现眼吧 [re: grip2]

 

 

//轉一貼:
回复人: zlj617(维他命) ( ) 信誉:100 2003-7-24 10:21:09 得分:10



代码区存放的是各函数代码块;堆区,存放存程序的动态数据;栈区,存放程序的局部数据;局部数据区存放程序的全局数据和静态数据,静态局部变量与全局变量共享全局数据区,函数结束时,静态局部变量不会消失,每次该函数调用时,不会为其重新分配空间,它始终驻留在全局数据区,直到程序运行结束,但静态局部变量只在定义它的函数中可见



Top

回复人: zlj617(维他命) ( ) 信誉:100 2003-7-24 10:22:01 得分:0



静态全局变量对组成该程序的其他源文件是无效的,如程序由一个源程序实现,则全局变量与静态全局变量没有区别



Top




--------------------
為了生活要向前看﹐理解生活要后看................

文章选项:

[精华] Re: 算了 我来现眼吧 [re: beyond_wyc]

 

 


       +--------------------------------------------+   
高地址


       |                                            | <-
命令行参数和环境变量


       |                                            |


       |--------------------------------------------| <-------   
栈底


       |                   
                      |


       |                    |                       |


       |                    v                       |


       |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| <-------   
栈顶


       |                                            |


       |                                            |


       |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|


       |                    ^                       |


       |                    |                       | 


       |                   
                      |


       |--------------------------------------------|


       |            
未初始化的数据                 | <-------- exec()赋初值0


       |--------------------------------------------|


       |             
初始化的数据                  |---\


       |--------------------------------------------|    \ exec()
从程序文件中读


       |                  
正文                     |    / (硬盘上的文件)


       |                                            |---/


       +--------------------------------------------+  
低地址

 

 

文章选项:

Re: 算了 我来现眼吧 [re: kevin_lee]

 

 

恩那,我也这么画 :)


--------------------
尽人事,听天命

文章选项:

Re: 请问堆和栈有什么区别? [re: yuan_weiqi]

 

 

堆是先进先出,栈是先进后出。

文章选项:

Re: 堆和栈 [re: carrot]

 

 

>对于栈是否在硬件级支持,其实也不全是了,像MIPS架构的CPU在硬件上就不支持栈,没有出栈、压栈指令

应该说, RISC体系结构的处理器一般都不在硬件上直接支持stack,因为没必要, 也不符合RISC的思想准则。出栈和压栈操作与一般的访存指令没有任何区别。而且RISC处理器一般也不会特别设一个sp寄存器,而是由该处理器的ABI规定使用哪一个General Purpose Register作为sp寄存器。而编译器都必须遵循该ABI


--------------------
http://jtager.sourceforge.net

编辑者: zhanrk (04-08-30 12:12)

文章选项:

Re: 请问堆和栈有什么区别? [re: yuan_weiqi]

 

 

见《UNIX环境高级编程》中文版第七章7.6节第127页:C程序空间的布局。

过去将stack译为堆栈。现在基本上都译成了。
Heap
译为

以下讨论假定楼主的分别为“heap”
stack”


一般而言:
1.
初始化的全局变量,放在数据段。未初始化的全局变量,放在未初始化数据段,一般为BSS段。函?br>诓康木蔡?static)放在数据段或者BSS段,与初始化与否有关。

2.
函数内部的局部自动变量(不通过malloc机制),使用进程或线程的栈空间。

3.
动态内存分配使用堆空间。不同的操作系统对堆有不同的管理方式。windows有局部堆与全局堆的?br>稹O附谖乙膊惶T诤芏嗲度胧絆S将称堆为内存池(memory pool)

如:stack_buf使用栈。


char global_buf[1024];


char global_c = 'A';


void func()


{


    char stack_buf[1024];


    static char static_buf[1024];


    char *heap_buf = malloc(1024);


    ...


}



 



数据段:global_c
BSS
段:global_buf, static_buf
栈:stack_buf
堆:heap_buf


补充说明几点:
1.
堆不一定就是从低地址向高地址增长。

不同的系统实现是不一样的。在许多嵌入式系统中,堆是从未初始化数据段到某一个高地址的。移
植过libcmalloc函数的朋友应该会很清楚这一点。一个系统的堆的位置与行为模式完全由系统程
序员来定义。

2.
栈也不一定是高地址向低地址增长。栈的位置也与系统有关。

有些系统将栈空间定义到一个未初始化的数组中,这样栈空间其实是在BSS段中。也可以将栈空间?br>alloc来分配,这样栈又落在了堆中。也可以用初始化为0的数组来定义栈空间。这样栈又落到数
据段中。

比如:UC/OS-II中,栈的增长方向是可以由程序员定义的。相信熟悉这个系统的朋友都有深刻体会


理论与实践并不完全相同。不同系统的行为是不大一样的。咱们需要鉴别、吸收。

但是堆与栈的作用基本上都是一样的。栈对CPU可见,是CPU指令分配空间的一种自然手段。对于C?br>镅远旧暇褪歉诓康木植孔远淞孔急傅摹T诨惚嘤镅约侗鹕希芏嗾豢占淠诒淞
慷急挥呕墒褂眉拇嫫髁恕eap_buf指向的内存空间为堆空间。而heap_buf指针变量自身使用的?br>诖婵占淙词钦豢占洹S呕罂赡芑崾褂眉拇嫫鳌?

以上愚见,谨供参考。



--------------------
┏━━━━━━┓
它山石
┗━━━━━━┛

文章选项:

原文地址:https://www.cnblogs.com/liangqihui/p/202989.html