![]() |
1
35
堆栈和堆并不像你想象的那么不同!诚然,有些操作系统确实存在堆栈限制。(其中一些也有令人讨厌的堆限制!) 但现在已经不是1985年了。
我的默认 堆栈大小 限制为10 MB。我的默认 是无限的。取消对堆栈大小的限制非常简单。(*咳嗽*[tcsh] 未限制堆栈大小 setrlimit() .) 和 堆
在Linux下,两者 堆栈 和 堆 通过虚拟内存进行管理。 就分配时间而言,即使在碎片严重的内存中进行堆搜索,也无法在内存的新页面中进行映射。 时间上的差异可以忽略不计! 不 malloc() 分配!)(这是一本书 惰性评估 ( 刚出现的 将调用构造函数,该构造函数可能会使用这些内存页…) 堆栈 或者 堆 malloc() 虽然被调出的页面需要被调回,这将是你最受欢迎的时间。 在所有这些事情中, ! 寿命(超出范围时)始终是决定因素。
修订如下:老兄,我被宠坏了!这里有些东西不对劲。。。我想,要么,要么,我,离基地太远了。或者其他人都是。或者,更有可能两者兼而有之。或者,只是可能,两者都不是。 不管答案是什么,我必须知道到底发生了什么! …这会很长的。请容忍我。。。
我在Windows上做了一些工作,但还不够权威。不幸的是,Mac OS/Darwin也没有。。。尽管Mac OS/Darwin/BSD已经足够接近了,我的一些知识还是流传了下来。 使用32位指针时,4GB(2^32)的地址空间会用完。 堆栈 + 堆 合并的是 usually limited to somewhere between 2-4 GB as other things need to get mapped in there.
在Linux/Unix/MacOS/Darwin/BSD下,您可以人为地约束 堆 这是(在tcsh中)的区别 “限制-h” . 或(在狂欢中)的 “ulimit-Sa” vs . 或者,以编程方式 里姆库尔 马克斯 结构限制 . 现在我们进入有趣的部分。关于 马丁约克密码 马丁 ! 很好的例子。尝试总是好的!) 马丁的 当然,默认情况下,他的代码不会在Mac上运行。但如果他先调用 “未限制堆栈大小” (tcsh)或 (猛击)。 问题的核心是:在一个古老(过时)的Linux RH9 2.4.x内核盒上测试,分配大量 堆 ,任何一个都可以在2到3 GB之间达到最高。(可悲的是,这台机器的RAM+交换的最高容量略低于3.5 GB。这是一个32位操作系统。这是 因此,在这方面确实没有限制 堆 Linux下的大小,而不是人工的大小。。。 在Mac上,有一个硬堆栈大小限制 65532千字节 . 这与事物在记忆中的布局有关。 苹果电脑似乎坚持自己的观点 共享系统库 以固定的偏移量限制两侧。你仍然可以跑步 使用“unlimit stacksize”,因为他只分配8MIB(<64MIB)之类的数据。 但他会用完的 堆栈 堆 . Sorry kid. Here's a Nickel. Go get yourself a better OS.
只要你把东西推到桌子上 堆栈 堆栈 相反,作为 堆 不 回避的理由 堆 存储这只是编码时需要注意的事情。 这带来了
然后,您可以得到大量的变量,这些变量都在代码的一个小的局部区域内使用,分散在许多虚拟内存页上。(例如,您在这个2k页面上使用了4个字节,在那个2k页面上使用了8个字节,以此类推,整个页面都是如此……) 所有这些都意味着您的程序需要交换大量页面才能运行。或者它会不断地交换页面。(我们称之为打击。) 堆栈 下一个话题。线程:是的,默认情况下线程仅限于非常小的堆栈。 单个线程堆栈过大将是一个问题!
关于 马丁·约克 堆栈帧:
当我想到 堆叠框架 堆叠框架 由返回地址、参数和本地数据组成。 我从来没有看到过任何限制的大小 . 这是有限制的 总的来说,但这就是全部 堆叠框架 There's a nice diagram and discussion of stack frames over on Wiki. 在Linux/Unix/MacOS/Darwin/BSD下,可以更改最大值 以编程方式以及 (tcsh)或 文件描述符 (猛击):
|
![]() |
2
29
堆栈是一段内存。堆栈指针指向顶部。可以将值推送到堆栈上并弹出以检索它们。
两者都被推到堆栈上,这会将堆栈指针向上移动:
现在调用函数并将返回地址放在堆栈上:
函数中有两个局部变量;2个字节中的一个和4个字节中的一个。对于这些,堆栈上保留了一个位置,但首先我们保存堆栈指针,以便通过向上计数知道变量的起始位置,通过向下计数找到参数。
如您所见,只要还有空间,就可以在堆栈上放置任何内容。否则,你会看到这个网站的名字。 |
![]() |
3
9
|
![]() |
4
5
如果您试图创建一个堆栈对象,该对象需要的内存比当前堆栈上可用的内存多,则会出现堆栈溢出,并发生不好的情况。一大类利用漏洞的代码故意试图创造这些或类似的条件。 堆栈没有划分为整数大小的块。它只是一个扁平的字节数组。它由类型为size\u t(非int)的“整数”索引。如果创建一个适合当前可用空间的大型堆栈对象,它将通过向上(或向下)移动堆栈指针来使用该空间。 正如其他人指出的,最好对大型对象使用堆,而不是堆栈。这避免了堆栈溢出问题。 编辑: |
![]() |
5
3
无论何时输入函数,堆栈都会增长以适应该函数中的局部变量。给予
看见 x86 Calling Conventions MSDN还为一些不同的调用冲突提供了一些很好的图表,包括 Sample Code resulting stack diagrams . |
![]() |
6
2
正如其他人所说,还不清楚你所说的“大型物体”是什么意思。。。然而,既然你问
我假设你只是指大于整数的任何东西。不过,正如其他人所指出的,堆栈没有整数大小的“插槽”——它只是内存的一部分,每个字节都有自己的地址。编译器根据变量的地址跟踪每个变量
第一
该变量的字节——这是使用运算符地址时得到的值(
|
![]() |
7
1
|
![]() |
8
1
堆栈大小是有限的。通常在创建进程时设置堆栈大小。如果在CreateThread()调用中未另行指定,则该进程中的每个线程都会自动获取默认堆栈大小。所以,是的:可以有多个堆栈“插槽”,但每个线程只有一个。而且它们不能在线程之间共享。 如果将大于剩余堆栈大小的对象放入堆栈,则会出现堆栈溢出,应用程序将崩溃。 因此,如果您有非常大的对象,请在堆上而不是堆栈上分配它们。堆只受虚拟内存量(比堆栈大一个数量级)的限制。 |
![]() |
9
0
|
![]() |
10
0
如何定义大型对象?我们说的是大于还是小于分配的堆栈空间的大小? 例如,如果您有如下内容:
根据您的系统,您可能会遇到segfault,因为根本没有足够的空间来存储对象。否则它会像其他任何对象一样存储。如果您在实际的物理内存中说话,那么您不必担心这一点,因为操作系统级别的虚拟内存将负责处理这一问题。 |
![]() |
11
0
“堆栈是整数的大小”,您的意思是“堆栈指针是整数的大小”。它指向堆栈的顶部,这是一个巨大的内存区域。嗯,比整数大。 |
![]() |
MaPo · Linux,设置锁定ICMP_过滤器选项 4 月前 |
![]() |
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 4 月前 |
![]() |
Bobby · 复合字面值总是左值吗? 4 月前 |
![]() |
9-Pin · C: 嵌套结构的堆栈内存分配 4 月前 |