堆栈上的总变量大小是否有限制? [英] Is there a limit for the total variables size on the stack?

查看:41
本文介绍了堆栈上的总变量大小是否有限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编码时,我们是否应该考虑对堆栈上创建的变量的总大小进行一些限制?如果是,我们应该在什么基础上做出决定?它是否依赖于操作系统、内存可用性等?是否有任何编译器选项可以检查这一点?

While coding should we consider some limit on the total size of variables created on the stack? If yes, on what basis should we decide it? Is it dependent on OS, Memory Availability etc? Are there any compiler options which can check this?

任何指向方向的指针也会有所帮助.

Any pointers in the direction will also be helpful.

推荐答案

这是 C 标准中用户不太友好的领域之一.

This is one of the less user-friendly areas of the C standard.

这完全依赖于实现,而且几乎不可能正确"地做到这一点.C 标准不保证您可以在不破坏堆栈的情况下定义哪些自动变量,或者当您这样做时会发生什么,或者测量堆栈使用或指定堆栈大小的任何方式,或者检测您即将用完的任何方式堆栈,可能会产生不可预测的结果.该标准甚至没有提到堆栈"这个词.

It's all entirely implementation-dependent, and pretty much impossible to do "properly". The C standard does not guarantee what automatic variables you can define without blowing the stack, or what happens when you do, or any way of measuring stack use or specifying stack size, or any way of detecting that you're about to run out of stack, perhaps with unpredictable results. The standard doesn't even mention the word "stack".

因此,您应该注意您正在使用多少堆栈,但是在嵌入式系统上多少可能是几千甚至更少,而在桌面系统上可能是 1MB 或更多.在 Windows 上,您几乎不关心堆栈 - 只要您没有在其上放置大量数组,或者递归到等于某个数组或列表大小的深度,那么您就可以了.在有限的系统上,甚至将文件名放在堆栈上也不一定是个好主意.但是,如果您只将内置类型和微型数组和结构放在堆栈上,并且如果您只递归到深度 log N,那么您在任何地方都会很好.如果你不正常,希望你会得到一个明显的崩溃,但你不能确定.

So, you should be mindful of how much stack you're using, but how much is too much could be a few k or even less on an embedded system, and 1MB or more on a desktop system. On Windows you barely care about stack - as long as you aren't putting vast arrays on it, or recursing to a depth equal to the size of some array or list, then you'll be fine. On limited systems it's not necessarily a good idea to put even a filename on the stack. But if you only ever put built-in types and tiny arrays and structs on the stack, and if you only ever recurse to depth log N, then again you'll be fine pretty much anywhere. Hopefully you'll get an obvious crash if you're not fine, but you can't be sure.

最关键的时间是您将代码移植到新系统时 - 如果您无法估计堆栈使用不是很多",那么您需要仔细测试.出于这个原因,如果您担心对有限系统的可移植性,那么您必须谨慎使用堆栈.至于保守"是什么意思,这有点取决于有限"是什么意思,但如果你对手机级别的有限"感兴趣,那么文件名的大小就是你可能在想的地方,应该这不是在堆上吗?",但当然上下文很重要:如果你的文件处理代码有 10 层,在每一层修改文件名,那么你不想在堆栈上这样做.如果它只有几层,并且你知道它不会被堆栈上已经有任何大的东西的代码调用,那么你可能会侥幸逃脱.

The most critical time is when you're porting code to a new system - if you can't estimate that stack use is "not very much", then you need to test carefully. For this reason, if you're worried about portability to limited systems, then you must be conservative with stack use. As for what "conservative" means, it sort of depends what "limited" means, but if you're interested in mobile-phone levels of "limited", then the size of a filename is about where you might be thinking, "should this be on the heap instead?", but of course context matters a lot: if your file-handling code has 10 layers, modifying the filename at each layer, then you don't want to be doing that on the stack. If it only has a couple of layers, and you know it won't be called by code that has anything big on the stack already, you can probably get away with it.

虽然我说的是手机",但现代智能手机更接近哦,用你需要的,就可以了"的桌面模式.如果您正在为类似 PIC 的东西编程(并坚持编写 C),那么基本上忘记可移植假设,并准确跟踪您正在使用的堆栈与可用堆栈的比较.

Although I say "phones", modern smartphones are closer to the desktop model of "oh, just use what you need, it'll be fine". If you're programming for something PIC-like (and insist on writing C), then basically forget about portable assumptions, and track exactly what stack you're using compared with what's available.

我想我不记得曾经遇到过以 0x6adb015 描述的方式工作的受保护操作系统,所以你甚至不能说无论我使用堆栈还是堆,它们都来自同一个池结束".他们不一定.我遇到的两个主要模型是:

I don't think I remember ever encountering a protected OS that works the way 0x6adb015 describes, so you can't even say "it doesn't matter whether I use stack or heap, they all come from the same pool in the end". They don't, necessarily. The two main models I've encountered are:

  • 堆栈地址空间是预先分配的(也许是已提交的,也许不是),所以你可以使用多少堆栈是有硬性限制的,即使有剩余内存,你的程序也会崩溃.

  • Stack address space is assigned up front (and perhaps committed, perhaps not), so there's a hard limit how much stack you can use, and any more than that your program crashes even if there's memory left.

堆栈是动态扩展的,因此您可以继续使用堆栈,直到内存不足.

Stack is extended dynamically, so you can keep using stack until you run out of memory.

因此,堆栈可能是比堆更有限的资源.正如 Mitch Wheat 所说,编译器(或链接器)选项可以改变该区域的大小,请查看您的手册了解详细信息.操作系统还可以提供运行时选项,例如 ulimit.我要补充一点,线程 API 可以让您指定新线程的堆栈大小.但同样,它完全依赖于实现.

So, stack could be a more limited resource than heap. As Mitch Wheat says, compiler (or linker) options can vary the size of this region, check your manual for details. The OS may also provide runtime options, such as ulimit. I'd add that thread APIs can let you specify the stack size for a new thread. Again, though, it's completely implementation-dependent.

这篇关于堆栈上的总变量大小是否有限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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