堆栈何时真正溢出? [英] When does the stack really overflow?

查看:34
本文介绍了堆栈何时真正溢出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无限递归是唯一的情况还是可能由于其他原因而发生?堆栈大小不是和堆一样按需增长吗?

Is infinite recursion the only case or can it happen for other reasons? Doesn't the stack size grow as needed same as heap?

抱歉,如果之前有人问过这个问题,如果是这样的话,希望能找到他们的链接.

Sorry if this question has been asked before, would appreciate links to them if that is the case.

推荐答案

我不能说所有平台,但碰巧的是,我刚刚花了一些时间处理 Windows .exe 文件(我的意思是,实际上在学习它们的二进制格式——我知道从某种意义上说,我们这里的所有人都使用可执行文件;)).我敢打赌,大多数其他平台都有类似的功能,但我对它们并不熟悉.

I can't speak for all platforms, but as it happens, I've just spent some time working with Windows .exe files (I mean, actually studying the binary format of them - I know in a sense all of us here work with executable files ;) ). I'm betting that most other platforms have similar capabilities, but I'm not immediate familiar with them.

部分文件格式本身包括两个与当前讨论相关的值:

Part of the file format itself includes two values relevant to the current discussion:

typedef struct _IMAGE_OPTIONAL_HEADER {
    ...
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    ...
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

来自 MSDN:

SizeOfStackReserve

要保留的字节数堆.仅由指定的内存SizeOfStackCommit 成员是在加载时提交;剩下的就是一次提供一页直到达到此保留大小.

The number of bytes to reserve for the stack. Only the memory specified by the SizeOfStackCommit member is committed at load time; the rest is made available one page at a time until this reserve size is reached.

SizeOfStackCommit

提交的字节数堆栈.

换句话说,链接器指定了程序堆栈的最大大小.如果您达到最大尺寸,您就会溢出 - 无论您如何达到最大尺寸.您可以编写一个简单的程序,只需分配一个大于最大堆栈大小的堆栈变量(例如,一个数组),就可以在一行代码中完成此操作.或者您可以通过无限(或有限,但非常深)递归来实现,或者仅通过分配太多堆栈变量来实现.

In other words, the linker specifies a maximum size for the program's stack. If you hit the maximum size, you overflow - no matter how you hit the maximum size. You could write a simple program to do it in one line of code just by allocating a single stack variable (say, an array) that's bigger than the maximum stack size. Or you could do it via infinite (or finite, but very deep) recursion, or just by allocating too many stack variables.

Microsoft 链接器在 X86 平台上将此值默认设置为 1MB(在 Itanium 系统上为 4MB).从表面上看,这对于现代系统来说似乎很小.但是,更现代的 Windows 版本对这些值的解释略有不同.它不是完全限制堆栈,而是限制堆栈将使用的物理内存.如果您的堆栈增长超出此范围,则会涉及虚拟内存,因此您应该还是不错的……假设您有足够的虚拟内存.

The Microsoft linker sets this value to 1MB by default on X86 platforms (4MB on Itanium systems). This seems small on the face of it, for a modern system. However, more modern versions of Windows interpret these values slightly differently. Instead of completely limiting the stack, it limits the physical memory the stack will use. If your stack grows beyond this, virtual memory will get involved, so you should still be good... assuming you have enough virtual memory.

请记住,即使在具有大量 RAM 和大量磁盘虚拟内存的现代系统上,也有可能耗尽内存.您只需要分配非常大量的数据.

Remember, it is possible to run out of memory, even on modern systems with huge amounts of RAM and plenty of virtual memory on disk. You just need to allocate really big amounts of data.

所以,长话短说:是否有可能在没有无限递归的情况下使堆栈溢出?确实.有可能吗?不是真的,除非您要分配非常大的对象.

So, long story short: is it possible to overflow the stack without infinite recursion? Definitely. Is it likely? Not really, unless you're allocating really huge objects.

这篇关于堆栈何时真正溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆