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

C 堆栈上的总变量大小是否有限制? 当编码时,我们应该考虑在堆栈上创建的变量的总大小的一些限制吗?如果是,我们应该在什么基础上作出决定?它是否取决于操作系统、内存可用性等?是否有任何编译器选项可以检查此问题,c,memory,memory-management,stack,C,Memory,Memory Management,Stack,任何指向该方向的指针都会有帮助。通常,进程的内存映射将有一个堆(malloc'ed memory)和堆栈(automatic memory)。 堆被分配到映射的顶部内存,堆栈增长到底部。 在任何情况下,堆栈指针和堆指针都不应冲突 简言之,堆栈大小与进程的内存映射有关 +------ | stack | | | V +------ | | free space | +----- | ^ | | | heap +------ 嵌入式系统也是如此。这是C标准中用户友好程度较低的领域之一 这完

任何指向该方向的指针都会有帮助。

通常,进程的内存映射将有一个堆(malloc'ed memory)和堆栈(automatic memory)。 堆被分配到映射的顶部内存,堆栈增长到底部。 在任何情况下,堆栈指针和堆指针都不应冲突

简言之,堆栈大小与进程的内存映射有关

+------
| stack
|  |
|  V
+------
|
| free space
|
+-----
|  ^
|  |
| heap
+------

嵌入式系统也是如此。

这是C标准中用户友好程度较低的领域之一

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

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

最关键的时刻是将代码移植到新系统时——如果不能估计堆栈使用“不是很多”,那么需要仔细测试。出于这个原因,如果您担心到有限系统的可移植性,那么您必须保守使用堆栈。至于“保守”意味着什么,这在某种程度上取决于“有限”意味着什么,但如果你对“有限”的手机级别感兴趣,那么文件名的大小就是你可能会想,“这应该放在堆上吗?”,但当然上下文关系很大:如果你的文件处理代码有10层,在每一层修改文件名,那么你就不想在堆栈上这样做了。如果它只有几个层,并且您知道它不会被已经在堆栈上有任何重要内容的代码调用,那么您可能可以不受影响

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

我想我不记得曾经遇到过像0x6adb015描述的那样工作的受保护操作系统,所以你甚至不能说“不管我使用堆栈还是堆,它们最终都来自同一个池”。不一定。我遇到的两个主要模型是:

  • 堆栈地址空间是预先分配的(可能是已提交的,也可能不是),所以您可以使用的堆栈数量有一个硬限制,超过这个限制,您的程序即使有内存也会崩溃

  • 堆栈是动态扩展的,所以您可以一直使用堆栈,直到内存耗尽


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

有编译器特定的选项来设置堆栈大小。你还没有提到你的编译器…请看@Mitch,我想要一个可跨操作系统移植的通用解决方案,所以没有提到编译器。在cygwin上运行时,我得到一个地址为
0x22cce4
的自动变量,堆分配为
0x660158
。堆没有向堆栈方向增长。我不认为“通常”是正确的。根据我的经验,在嵌入式系统上比在桌面系统上更是如此。桌面应用程序通常每个堆有一个以上的堆栈(多线程),在这种情况下,这种方法没有意义。+1表示不依赖于实现,但以它们为例。