返回信息流☆─────────────────────────────────────☆
odark (odark) 于 (Fri Dec 5 21:11:59 2008) 提到:
☆─────────────────────────────────────☆
zieckey (他们都叫我小宝*单车旋风族之霄寒风) 于 (Fri Dec 5 21:36:06 2008) 提到:
简单点说:
栈和堆都是内存空间,栈由操作系统自己维护,堆上的空间用户自己维护,用多少就要记得释放多少
【 在 odark 的大作中提到: 】
☆─────────────────────────────────────☆
tsunami (风之子) 于 (Fri Dec 5 23:48:42 2008) 提到:
精辟~
☆─────────────────────────────────────☆
ydy (winter rock) 于 (Sat Dec 6 00:01:14 2008) 提到:
可以从作用域,生命周期,链接性等方面考虑。
【 在 odark 的大作中提到: 】
☆─────────────────────────────────────☆
odark (odark) 于 (Sat Dec 6 00:12:11 2008) 提到:
呵呵。。。,谢了!
☆─────────────────────────────────────☆
fwq (fwq) 于 (Sat Dec 6 10:14:38 2008) 提到:
一般来讲 局部变量 函数调用的参数 等存在于栈中。函数调用时 调用函数会将被调用函数的参数入栈 被调用函数通过移动栈顶指针来为局部变量分配空间,函数调用返回时反向移动栈顶指针。这些动作都是编译时完成的 高级代码中没有体现出来,可以看看编译后的汇编代码。 ebp esp寄存器用来管理栈。
堆是另外一种内存管理方式,需通过调用系统函数来分配和释放,应用程序可以直接控制。
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Sat Dec 6 10:49:43 2008) 提到:
函数调用的时候使用栈空间,例如printf。
分配内存的时候使用堆空间,例如malloc。
操作系统一般会把堆和栈放在同一段内存里,堆和栈的指针分别从两端向中间增长。例如,堆指针从低端向上增长,栈指针从高端向下增长,如果两个指针碰到一起就是内存空间占满了。
☆─────────────────────────────────────☆
flyingkisser (齐天大猫) 于 (Sat Dec 6 11:14:42 2008) 提到:
"操作系统一般会把堆和栈放在同一段内存里",从何而来?可有依据?
【 在 dragon2000 (龙之梦工作室) 的大作中提到: 】
: 函数调用的时候使用栈空间,例如printf。
: 分配内存的时候使用堆空间,例如malloc。
: 操作系统一般会把堆和栈放在同一段内存里,堆和栈的指针分别从两端向中间增长。例如,堆指针从低端向上增长,栈指针从高端向下增长,如果两个指针碰到一起就是内存空间占满了。
: ...................
☆─────────────────────────────────────☆
sunway (sunway) 于 (Sat Dec 6 15:00:45 2008) 提到:
太教科书了..
堆栈不在同一“段”内存。用linux的话说,他们属于不同的vm_area
堆栈之间还夹着其他vm_area,如自己mmap的,shared library..
【 在 dragon2000 (龙之梦工作室) 的大作中提到: 】
: 函数调用的时候使用栈空间,例如printf。
: 分配内存的时候使用堆空间,例如malloc。
: 操作系统一般会把堆和栈放在同一段内存里,堆和栈的指针分别从两端向中间增长。例如,堆指针从低端向上增长,栈指针从高端向下增长,如果两个指针碰到一起就是内存空间占满了。
: ...................
☆─────────────────────────────────────☆
ZenZero (ZenZero) 于 (Sat Dec 6 18:42:40 2008) 提到:
栈是一段后进先出的内存,是一种数据结构,主要用于自动变量的分配,程序载入时由Loader根据链接时指定的栈大小自动向操作系统申请内存,其管理由机器指令直接提供支持,SS寄存器指向其段描述符,也同时指定了栈底,ESP寄存器指向当前栈顶,EBP寄存器一般用于平衡堆栈,PUSHXX/POPXX用于入栈和出栈...
堆是一个内存池,操作系统会维护一个系统堆,堆的大小反映了可用内存的数量,程序载入时会由Loader根据链接时指定的堆参数向操作系统申请 分配或者保留 指定大小的堆,操作系统把已分配的堆标记为已用,然后分配给应用程序,称之为用户堆,用户堆是由运行时库函数来管理的,对于C程序而言就是crt,然后程序就可以通过new/malloc向crt动态申请内存。堆一般是通过链表来管理的...
所以堆(Heap)和栈(Stack)基本上是完全不同的两个东西..
曾经因为这个问题被国内很多半吊子文章忽悠了很久的初学者飘过~~
☆─────────────────────────────────────☆
Bergwolf (计忆邮心|Kinight) 于 (Sat Dec 6 20:13:56 2008) 提到:
伊指的应该是进程自己的地址空间
【 在 sunway (sunway) 的大作中提到: 】
: 太教科书了..
: 堆栈不在同一“段”内存。用linux的话说,他们属于不同的vm_area
: 堆栈之间还夹着其他vm_area,如自己mmap的,shared library..
☆─────────────────────────────────────☆
urright (hehe) 于 (Sat Dec 6 23:06:59 2008) 提到:
不学汇编的后果。
☆─────────────────────────────────────☆
flyingkisser (齐天大猫) 于 (Sat Dec 6 23:49:31 2008) 提到:
re
【 在 ZenZero (ZenZero) 的大作中提到: 】
: 栈是一段后进先出的内存,是一种数据结构,主要用于自动变量的分配,程序载入时由Loader根据链接时指定的栈大小自动向操作系统申请内存,其管理由机器指令直接提供支持,SS寄存器指向其段描述符,也同时指定了栈底,ESP寄存器指向当前栈顶,EBP寄存器一般用于平衡堆栈,
: 堆是一个内存池,操作系统会维护一个系统堆,堆的大小反映了可用内存的数量,程序载入时会由Loader根据链接时指定的堆参数向操作系统申请 分配或者保留 指定大小的堆,操作系统把已分配的堆标记为已用,然后分配给应用程序,称之为用户堆,用户堆是由运行时库函数来管理
: 所以堆(Heap)和栈(Stack)基本上是完全不同的两个东西..
: ...................
☆─────────────────────────────────────☆
myou (纯净半方糖) 于 (Sun Dec 7 00:10:32 2008) 提到:
图书馆里面有本书,名字叫《深入理解计算机系统》,书上讲的很容易懂。
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Sun Dec 7 00:25:36 2008) 提到:
抱歉我不负责举证。
【 在 flyingkisser 的大作中提到: 】
: "操作系统一般会把堆和栈放在同一段内存里",从何而来?可有依据?
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Sun Dec 7 00:27:27 2008) 提到:
您可以不看教科书去自己看linux的,不过我没提到linux,或者它的具体实现细节。
【 在 sunway 的大作中提到: 】
: 太教科书了..
: 堆栈不在同一“段”内存。用linux的话说,他们属于不同的vm_area
: 堆栈之间还夹着其他vm_area,如自己mmap的,shared library..
☆─────────────────────────────────────☆
sunway (sunway) 于 (Sun Dec 7 14:23:59 2008) 提到:
在进程的线性地址空间上堆栈中间隔着各种东西啊,用pmap看一下
【 在 Bergwolf (计忆邮心|Kinight) 的大作中提到: 】
: 伊指的应该是进程自己的地址空间
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Sun Dec 7 16:25:15 2008) 提到:
堆和栈的概念在DOS 3.3甚至更早的时候就已经有,用过Turbo C或者Turbo Pascal集成开发环境的就会知道。
具体的操作系统的实现细节和理论有出入,没有什么奇怪,而且不同系统也可以有不同的细节。正如TCP/IP并不严格遵守OSI七层网络模型,至于为什么破坏了模型的理论完整性,它当然有自己的理由。
但是操作系统的细节怎么变,似乎并不影响堆和栈的概念本身的由来,以及它们共同利用内存的原始设计理念吧。
【 在 sunway 的大作中提到: 】
: 在进程的线性地址空间上堆栈中间隔着各种东西啊,用pmap看一下
☆─────────────────────────────────────☆
Bergwolf (计忆邮心|Kinight) 于 (Sun Dec 7 19:43:31 2008) 提到:
看了,不过确实还是如他所说,heap和stack是从线性地址的两端开始涨的
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void F();
void J(int a)
{
a++;
printf("a=%d\n",a);
F(a);
}
void F(int a)
{
char* b = malloc(a);
memset(b, 0, a);
J(a);
}
int main()
{
int a = 1;
F(a);
return 0;
}
两次抓取的结果对比:
26310: ./a.out
08048000 4K r-x-- /home/gigi/test/a.out
08049000 4K rw--- /home/gigi/test/a.out
0927e000 1145756K rw--- [ anon ] ----------------------这应该就是heap吧
b7ebc000 4K rw--- [ anon ]
b7ebd000 1364K r-x-- /lib/i686/cmov/libc-2.7.so
b8012000 4K r---- /lib/i686/cmov/libc-2.7.so
b8013000 8K rw--- /lib/i686/cmov/libc-2.7.so
b8015000 12K rw--- [ anon ]
b8029000 12K rw--- [ anon ]
b802c000 104K r-x-- /lib/ld-2.7.so
b8046000 8K rw--- /lib/ld-2.7.so
bf74f000 3040K rw--- [ stack ]
total 1150320K
26310: ./a.out
08048000 4K r-x-- /home/gigi/test/a.out
08049000 4K rw--- /home/gigi/test/a.out
0927e000 1603972K rw--- [ anon ]
b7ebc000 4K rw--- [ anon ]
b7ebd000 1364K r-x-- /lib/i686/cmov/libc-2.7.so
b8012000 4K r---- /lib/i686/cmov/libc-2.7.so
b8013000 8K rw--- /lib/i686/cmov/libc-2.7.so
b8015000 12K rw--- [ anon ]
b8029000 12K rw--- [ anon ]
b802c000 104K r-x-- /lib/ld-2.7.so
b8046000 8K rw--- /lib/ld-2.7.so
bf6c4000 3596K rw--- [ stack ]
total 1609092K
【 在 sunway (sunway) 的大作中提到: 】
: 在进程的线性地址空间上堆栈中间隔着各种东西啊,用pmap看一下
☆─────────────────────────────────────☆
ZenZero (ZenZero) 于 (Sun Dec 7 20:29:38 2008) 提到:
堆的“涨”和栈的涨是完全是两个不同位面的事情,没有比较的意义,只能这么说了...
神不是万能的,但希洛是无所不能的~~
【 在 Bergwolf 的大作中提到: 】
: 看了,不过确实还是如他所说,heap和stack是从线性地址的两端开始涨的
: #include <stdio.h>
: #include <string.h>
: ...................
☆─────────────────────────────────────☆
Bergwolf (计忆邮心|Kinight) 于 (Mon Dec 8 00:32:14 2008) 提到:
我只是想说明dragon2000说的教科书上的堆栈的位置和现实并不违背。。。
【 在 ZenZero (ZenZero) 的大作中提到: 】
: 堆的“涨”和栈的涨是完全是两个不同位面的事情,没有比较的意义,只能这么说了...
: 神不是万能的,但希洛是无所不能的~~
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Mon Dec 8 13:10:21 2008) 提到:
莫非您打算一个个操作系统地核实?任重道远啊:
System/360、Mutics、Unix version xxx、CP/M、VMS、DOS x.x、OS 2、Minix、BSD、Macintosh、BeOS……
如果您把IPX、ATM等所有的网络协议都看一遍,会发现没有一个协议是严格遵守OSI七层模型的。或许您可以凭这点推翻OSI模型了。
【 在 flyingkisser 的大作中提到: 】
: windows平台肯定不是如此。
: 根本就是两码子事。
☆─────────────────────────────────────☆
ZenZero (ZenZero) 于 (Mon Dec 8 14:56:49 2008) 提到:
问题是您说的"操作系统一般会把堆和栈放在同一段内存里"仅仅在DOS实模式,并且用TC的TINY、SMALL、MEDIUM这三种内存模型编译时才会发生...而这是不符合任何一个现代多任务操作系统的实现方式的...
而且堆指针这种东西因为要考虑到碎片问题,随堆分配算法的不同,其分配顺序是不同的,因此无法预测下次分配的"指针"增长方向...
至于两个指针碰在一起就是内存空间占满了,抱歉这只是十几年前某些教科书不负责任的说法..
[QUOTE]操作系统一般会把堆和栈放在同一段内存里,堆和栈的指针分别从两端向中间增长。例如,堆指针从低端向上增长,栈指针从高端向下增长,如果两个指针碰到一起就是内存空间占满了。[/QUOTE]
【 在 dragon2000 的大作中提到: 】
: 莫非您打算一个个操作系统地核实?任重道远啊:
: System/360、Mutics、Unix version xxx、CP/M、VMS、DOS x.x、OS 2、Minix、BSD、Macintosh、BeOS……
: 如果您把IPX、ATM等所有的网络协议都看一遍,会发现没有一个协议是严格遵守OSI七层模型的。或许您可以凭这点推翻OSI模型了。
☆─────────────────────────────────────☆
ZenZero (ZenZero) 于 (Mon Dec 8 14:57:46 2008) 提到:
为什么网断了啊,只能上论坛了,哭~~
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Mon Dec 8 16:46:04 2008) 提到:
您所解释的涉及“具体实现”的原因,我在前面已经提过了吧:
“具体的操作系统的实现细节和理论有出入,没有什么奇怪,而且不同系统也可以有不同的细节。正如TCP/IP并不严格遵守OSI七层网络模型,至于为什么破坏了模型的理论完整性,它当然有自己的理由。”
什么才叫“现代”,什么才叫“过时”?您说是十几年前的教科书不负责任,有没有想过,您现在的议论在十几年之后被人看见,也会有人说是不负责任的?
我纯粹是解释“堆”和“栈”的由来,也没有针对特定的操作系统。恐怕当时的“现代”操作系统,当时的“先进”设计理念不能跟今天相提并论吧?
而且,对于任何一种设计理念,谁敢保证不会以某种形式应用到现代甚至未来的系统中呢?函数式编程也已经算是很古老了吧,早就应该扔进历史的垃圾堆了吧?现在多核时代,又开始引起关注了。为什么?那是一种理念,而不是具体实现。
【 在 ZenZero 的大作中提到: 】
: 问题是您说的"操作系统一般会把堆和栈放在同一段内存里"仅仅在DOS实模式,并且用TC的TINY、SMALL、MEDIUM这三种内存模型编译时才会发生...而这是不符合任何一个现代多任务操作系统的实现方式的...
: 而且堆指针这种东西因为要考虑到碎片问题,随堆分配算法的不同,其分配顺序是不同的,因此无法预测下次分配的"指针"增长方向...
: 至于两个指针碰在一起就是内存空间占满了,抱歉这只是十几年前某些教科书不负责任的说法..
: ...................
☆─────────────────────────────────────☆
AAJ (大卫) 于 (Mon Dec 8 16:53:53 2008) 提到:
问一下下面那些是怎么查看的呢?
【 在 Bergwolf 的大作中提到: 】
: 看了,不过确实还是如他所说,heap和stack是从线性地址的两端开始涨的
: #include <stdio.h>
: #include <string.h>
: ...................
☆─────────────────────────────────────☆
sunway (sunway) 于 (Mon Dec 8 17:15:02 2008) 提到:
pmap <pid>
【 在 AAJ (大卫) 的大作中提到: 】
: 问一下下面那些是怎么查看的呢?
☆─────────────────────────────────────☆
xiecaiji (wbc粉丝团----饼干---谁说装不像) 于 (Mon Dec 8 17:33:54 2008) 提到:
好深
☆─────────────────────────────────────☆
FadeToBlack (Patz) 于 (Mon Dec 8 17:58:03 2008) 提到:
我能問一下,TCP/IP是標準,那么堆棧指針碰到一起代表內存滿了也是標準嗎?
【 在 dragon2000 的大作中提到: 】
: 您所解释的涉及“具体实现”的原因,我在前面已经提过了吧:
: “具体的操作系统的实现细节和理论有出入,没有什么奇怪,而且不同系统也可以有不同的细节。正如TCP/IP并不严格遵守OSI七层网络模型,至于为什么破坏了模型的理论完整性,它当然有自己的理由。”
: 什么才叫“现代”,什么才叫“过时”?您说是十几年前的教科书不负责任,有没有想过,您现在的议论在十几年之后被人看见,也会有人说是不负责任的?
: ...................
☆─────────────────────────────────────☆
flyingkisser (齐天大猫) 于 (Mon Dec 8 18:06:20 2008) 提到:
别和他争了,没意义,这样争是浪费自己的时间。反正答案很清楚。
【 在 FadeToBlack (Patz) 的大作中提到: 】
: 我能問一下,TCP/IP是標準,那么堆棧指針碰到一起代表內存滿了也是標準嗎?
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Mon Dec 8 22:59:19 2008) 提到:
不要把标准看作是什么高不可攀的东西,标准只不过是一定范围内大家遵守的一个规范而已。至于为什么会遵守,既有技术的原因,也有商业利益的博弈。事实上TCP/IP也不见得是很好的具体实现方案。
堆栈指针碰到一起代表内存用光了,当然可以算一个标准。不过不是国际标准,而是设计某些系统的时候,开发者内部约定的一个标准。出了这个范围,谁愿意遵守就遵守,又不是强制要求的。
您还可以继续问:堆栈指针相碰的设计会过时,那么TCP/IP设计会过时吗?
一个答案是:不管什么时候,那是迟早的事。
【 在 FadeToBlack 的大作中提到: 】
: 我能問一下,TCP/IP是標準,那么堆棧指針碰到一起代表內存滿了也是標準嗎?
☆─────────────────────────────────────☆
ki (谁) 于 (Tue Dec 9 14:54:56 2008) 提到:
咳。堆栈指针居然可以碰到一块儿的。这是在讨论 286 还是 386 啊。
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Tue Dec 9 18:34:16 2008) 提到:
如果论时间,堆和栈的概念出现的时间比286、386早多了。不过讨论这个问题根本不需要关心具体的机型。
对了,C语言出来的时候,286、386连影子都没有呢。C语言早就“过时”了吧,还讨论它干什么?象Java、Ruby这些才够“现代”啊,对不对?
【 在 ki 的大作中提到: 】
: 咳。堆栈指针居然可以碰到一块儿的。这是在讨论 286 还是 386 啊。
☆─────────────────────────────────────☆
FadeToBlack (Patz) 于 (Tue Dec 9 22:03:06 2008) 提到:
好的,貓哥。
【 在 flyingkisser 的大作中提到: 】
: 别和他争了,没意义,这样争是浪费自己的时间。反正答案很清楚。
☆─────────────────────────────────────☆
dragon2000 (龙之梦工作室) 于 (Wed Dec 10 10:08:14 2008) 提到:
总会有人认为堆和栈的概念是从天上掉下来的,而且认为堆栈从来就是自己知道的那个样子,而且永远都是这个样子。操作系统只看Windows和Linux,就觉得代表了整个世界。
如果把整个世界上可以称为“计算机”的东西都加起来,PC不知道能有多大比例。即使以现代的眼光看,有多少嵌入式的系统可以装Windows和Linux?有多少单片机非要多任务多用户系统不可的?又有多少内存给堆栈?
按相对论的说法,当您的眼光仅局限于自己的惯性系里面,觉得自己的时钟很准,没有人会说您是错的。不过您看见别人的惯性系里面的时钟慢了,提出自己的怀疑当然可以,最好不要拿着自己的时钟要给别人校正时间。认为自己是对的就要强迫别人接受,不准讨论不准争辩,恐怕才是最不负责任的态度。人人都有个大脑去做分析和判断,我不信经过争论和思考还能够导致误人子弟。什么事都想当然,当然最省事,不用花时间了。
我的话是写给愿意刨根问底,还有哪怕一点点求知欲的同学看的。我的时间也很宝贵,不过只要有人愿意讨论我都尽量回答,不认为这是浪费时间。当然集中看技术方面的问题。不爱看的就哪儿凉快呆哪儿好了。
☆─────────────────────────────────────☆
sunway (sunway) 于 (Wed Dec 10 10:12:57 2008) 提到:
bm快合了吧
【 在 dragon2000 (龙之梦工作室) 的大作中提到: 】
: 总会有人认为堆和栈的概念是从天上掉下来的,而且认为堆栈从来就是自己知道的那个样子,而且永远都是这个样子。操作系统只看Windows和Linux,就觉得代表了整个世界。
: 如果把整个世界上可以称为“计算机”的东西都加起来,PC不知道能有多大比例。即使以现代的眼光看,有多少嵌入式的系统可以装Windows和Linux?有多少单片机非要多任务多用户系统不可的?又有多少内存给堆栈?
: 按相对论的说法,当您的眼光仅局限于自己的惯性系里面,觉得自己的时钟很准,没有人会说您是错的。不过您看见别人的惯性系里面的时钟慢了,提出自己的怀疑当然可以,最好不要拿着自己的时钟要给别人校正时间。认为自己是对的就要强迫别人接受,不准讨论不准争辩,恐怕才
: ...................
☆─────────────────────────────────────☆
ZenZero (ZenZero) 于 (Wed Dec 10 11:56:20 2008) 提到:
诚然,您说的许多话我并不能反驳,但是,如果说对于自然界的某些罕见却美丽的东西人们通常怀有强烈的好奇心的话,那么在计算机的世界里,事情恰恰是相反的。对于一辈子难以遇到却在某些情况下存在的理论,至少我是兴趣缺缺的。尤其在编程实践中,许多算法只有在特定硬件特定需求的情况下才有其合理性,并且也仅仅如此而已。如果有一天发现在宇宙的某个地方正负电荷相互排斥了,那么必然会带来整个物理理论界翻天覆地的变革,然而如果有一天告诉你某种计算机里栈向上生长了,大多数人可能只会“哦”一声就过去了,甚或某“资深人士”会甩几句粗口以示其不屑。
所以您的说法很多时候是很有启迪性的,但放在CPP版,对不起,我们不是孔乙己,我们也不关心“茴”字的四种写法。
【 在 dragon2000 的大作中提到: 】
: 总会有人认为堆和栈的概念是从天上掉下来的,而且认为堆栈从来就是自己知道的那个样子,而且永远都是这个样子。操作系统只看Windows和Linux,就觉得代表了整个世界。
: 如果把整个世界上可以称为“计算机”的东西都加起来,PC不知道能有多大比例。即使以现代的眼光看,有多少嵌入式的系统可以装Windows和Linux?有多少单片机非要多任务多用户系统不可的?又有多少内存给堆栈?
: 按相对论的说法,当您的眼光仅局限于自己的惯性系里面,觉得自己的时钟很准,没有人会说您是错的。不过您看见别人的惯性系里面的时钟慢了,提出自己的怀疑当然可以,最好不要拿着自己的时钟要给别人校正时间。认为自己是对的就要强迫别人接受,不准讨论不准争辩,恐怕才是最不负责任的态度。人人都有个大脑去做分析和判断,我不信经过争论和思考还能够导致误人子弟。什么事都想当然,当然最省事,不用花时间了。
: ...................
这是一条镜像帖。来源:北邮人论坛 / cpp / #17383同步于 2008/12/10
CPP机器人发帖
[合集] 一直没弄明白堆和栈有啥具体区别,google下没得到具体的
shenlei
2008/12/10镜像同步0 回复
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。