【问题标题】:Is there a maximum limit to the size of a variable that should be allocated on a stack?应该在堆栈上分配的变量的大小是否有最大限制?
【发布时间】:2011-01-10 06:57:53
【问题描述】:

我在 C 中声明了一个大小大于 1024 字节的结构变量。在运行 Coverity(静态代码分析器应用程序)时,它会报告此堆栈变量大于 1024 字节,因此会导致错误。 我想知道我是否需要担心这个警告?单个堆栈变量的大小真的有最大限制吗?

谢谢, 车

【问题讨论】:

  • 选择 1024 完全是任意的,512 字节的变量也可能是“错误原因”。并且 2048 字节的变量不会使它的可能性增加一倍。用一磅盐来接受这个建议。

标签: c struct variables stack


【解决方案1】:

它试图保护您免受堆栈溢出的问题,由于执行路径不同,在测试中很难找到。主要是因为这个原因 - 在堆栈上分配大量数据被认为是不好的形式。不过,您只有在嵌入式系统上真正可能遇到真正的问题。

换句话说,它对它认为堆栈上的过多数据设置了任意限制。

【讨论】:

    【解决方案2】:

    Stack, heap, low, high VM -- Nuts,对于第一个线程,堆栈在顶部 pf 64 位 VM,应该没有限制,所以这似乎是一个 gcc/c 编译器错误,用于本地自动“int x[2621440];”我得到 SIGSEGV。编译器应该让第一个线程堆栈增长直到它到达堆,这在一个 160 亿字节的 VM 中目前不太可能。最友好的事情是将其称为编译器“限制”。 (在不久前的测试中,可能是在 Solaris SPARC 上,似乎局部变量的处理速度比全局变量快。想想吧!)

    【讨论】:

      【解决方案3】:

      尝试使用大量堆栈空间并不是一个好主意。

      这是默认 gcc 堆栈大小的链接:http://www.cs.nyu.edu/exact/core/doc/stackOverflow.txt

      另外,您可以指定--stack,xxxxx 来自定义堆栈大小,因此最好假设xxxxx 是一个小数字并坚持堆分配。

      【讨论】:

        【解决方案4】:

        正如我所见,C 编译器(turbo)为变量提供了 64000k 的最大大小。如果我们需要更大的尺寸,则将其声明为“巨大”。

        【讨论】:

        • 当我将变量声明为 int a[1000][1000] 时,我看到了同样的消息。编译器显示“数组大小太大”的错误消息。当我看到帮助时,它具有相同的信息
        【解决方案5】:

        如果您的函数参与(直接或间接)递归,那么在堆栈上分配大量将限制递归深度并可能会破坏堆栈。在 Windows 下,此堆栈保留默认为 1MB,尽管您可以使用链接器命令静态增加它。堆栈会随着使用而增长,但操作系统有时无法扩展它。我会在我的网站here 上更详细地讨论这个问题。

        【讨论】:

          【解决方案6】:

          是的。当然,它受到系统地址空间的限制。它还受到操作系统分配给堆栈的空间量的限制,通常在程序启动后无法更改,但可以事先更改(通过启动过程或可执行文件的属性)。快速浏览一下,我的 OS X 系统上的最大堆栈大小为 8 MiB,而在 Linux 上为 10 MiB。在某些系统上,您甚至可以为您启动的每个不同线程分配不同数量的堆栈,尽管这样做的用处有限。大多数编译器还对单个堆栈帧中允许的数量有另一个限制。

          在现代桌面上,除非函数是递归的,否则我不会担心 1k 堆栈分配。如果您正在编写嵌入式代码或在 OS 内核中使用的代码,那将是一个问题。 Linux 内核中的代码仅允许 64 KiB 堆栈或更少,具体取决于配置选项。

          【讨论】:

          • “在某些系统上,您甚至可以为您启动的每个不同线程分配不同数量的堆栈,尽管这样做的用处有限”。它在默认很小的系统上变得很有用 - 你在桌面 Linux 上看不到需要,但你会在一些具有预分配堆栈且没有虚拟内存的嵌入式系统上。
          【解决方案7】:

          这篇关于堆栈大小的文章很有趣http://www.embedded.com/columns/technicalinsights/47101892?_requestid=27362

          是的,它是否依赖于操作系统,也依赖于其他事物。抱歉这么含糊。您还可以在 gcc 集合中挖掘一些代码来测试堆栈大小。

          【讨论】:

            【解决方案8】:

            变量的最大大小受堆栈最大大小的限制(具体来说,当前使用的堆栈剩余多少,包括来自堆栈上较高层的函数的变量和参数以及进程帧开销)。

            在 Windows 上,第一个线程的堆栈大小是可执行文件 set during linking 的属性,而线程的堆栈大小可以在 thread creation 期间指定。

            在 Unix 上,第一个线程的堆栈大小通常仅受其增长空间的限制。根据特定 Linux 分配内存的方式和您对共享对象的使用,这可能会有所不同。线程的stacksize也可以在thread creation期间指定。

            【讨论】:

              猜你喜欢
              • 2011-01-04
              • 2013-11-04
              • 2014-05-17
              • 2023-04-10
              • 2021-03-15
              • 2011-04-14
              • 2012-03-31
              • 2021-07-09
              • 2018-06-29
              相关资源
              最近更新 更多