【问题标题】:Is there a limit on how many local variables we can declare in C?我们可以在 C 中声明的局部变量的数量是否有限制?
【发布时间】:2022-01-11 05:15:26
【问题描述】:

考虑到一旦调用函数(在将变量推送给函数之后),C 中函数内的局部变量就会被推送到堆栈中,在堆栈缓冲区之前对所述变量的数量是否有任何限制溢出?还是该限制仅由确定的主机拥有的 RAM 量给出?

我试图通过创建一个 4,6gb .C 文件来测试这一点,该文件具有一个声明了 25000*13 个变量并初始化为 0 的函数。所述函数在 main() 内部被调用,但它编译得很好(使用 - O0) 并且它没有崩溃。

【问题讨论】:

  • 在 Windows、macOS 和 Linux 上,默认堆栈大小限制为 1-8 MiB。
  • 通过了解这个,您希望解决什么问题
  • @Passerby “帽子”符号也用于求幂。虽然我很困惑。所以它真的是“*”而不是“^”。
  • @KarlKnechtel 是否需要解决问题?寻求更深入的理解是一个令人钦佩的目标。

标签: c memory callstack variable-declaration


【解决方案1】:

例如根据 C 标准(5.2.4.1 翻译限制)

1 实现应至少能够翻译和执行 一个程序,其中至少包含一个实例 以下限制:

——一个翻译单元中有 4095 个外部标识符

— 511 个标识符,在一个块中声明了块范围

【讨论】:

  • 这是最低限度的。它没有回答最大值是多少:)
  • @0___________ 最大值由实现定义。
  • 还有 127 个嵌套块。那么511*127局部变量呢?加上 127 个函数参数...
  • @Shawn 该标准不要求编译器支持同时达到所有限制。 “实施应能够翻译和执行至少一个程序,该程序包含以下每个限制的至少一个实例。”因此,必须有一个具有 511 标识符的块范围的程序可以成功编译和执行。还有一个可以成功编译和执行的具有127个嵌套块的程序。但它们不必是同一个程序。
【解决方案2】:

主线程的默认堆栈大小在 macOS 上为 8 MiB(来自 ld 手册页),在 Linux 上为 2 MiB(根据 --stack 开关 here),在 Windows 上为 1 MiB(根据 @ 987654322@)。在程序中创建的其他线程可能具有较小的堆栈。 (注意:引用的各种来源使用“MB”或“Mb”;我在上下文中将它们解释为 1,048,576 字节 = 1 MiB。)

将程序链接到可执行文件时可以请求不同的堆栈大小。

函数将堆栈空间用于各种事情,包括传递参数、建立堆栈帧以抛出异常、有时调试信息和临时工作空间,因此堆栈使用的内存量与数量之间没有直接关系可以定义的变量。

【讨论】:

    【解决方案3】:

    因为你不问最低要求,所以我会写关于 C 标准的文章

    现代的符合标准的编译器现在没有设置任何限制(微软不计入,因为它不符合标准)。您受到可用计算机资源的限制。

    工具链的另一部分(链接器、对象和可执行文件限制等)可能会设置一些额外限制,但现代主线编译器通常没有任何限制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 2021-11-16
      相关资源
      最近更新 更多