c++ 如何为某个程序确定合适的堆栈大小?[副本]

rsl1atfo  于 2023-05-24  发布在  其他
关注(0)|答案(2)|浏览(202)

此问题已在此处有答案

How to determine maximum stack usage?(5个答案)
5小时前关闭
注意,编译器的默认堆栈大小是1 MB,要增加堆栈大小,必须在链接器>系统配置中手动输入堆栈大小。有没有一种方法可以根据我写的代码来查看我需要的堆栈大小,这样我就可以手动输入堆栈大小,而不会给它太多?

9vw9lbht

9vw9lbht1#

一般来说,你不知道在程序执行之前需要多少堆栈。考虑这个人为的例子:

void foo() {
     int x;  // on the stack
     std::cin >> x;
     if (x) foo();
     std::cout << x;
 }

在没有优化将递归转换为循环的情况下,无论堆栈有多大,foo都可以超过它,这取决于用户输入。
一般来说,不可能事先决定要使用多少堆栈。

6qqygrtg

6qqygrtg2#

这是嵌入式软件普遍关心的问题。很难准确估计所需的堆栈大小,但有几种常见的方法:

  • 不要在堆栈上分配较大的对象
  • 在堆栈的末尾存储一个“幻数”,并有一种机制来检测它是否被覆盖。
  • 在程序开始时在堆栈区域写入一个固定的字节模式,并在结束时查看有多少字节模式被覆盖,以查看程序的给定运行使用了多少堆栈空间。

这些实验方法在非嵌入式系统上的可行性可能会有所不同,但通过存储堆栈顶部的(近似)初始位置,然后将当前位置与之进行比较,在任何给定时间估计堆栈使用情况应该相当简单。
下面的代码显示了这种方法:

#include <stdio.h>

void *stack_base;

void print_stack_size()
{
    char c;   // "c" is allocated on the stack at the current position
    printf("Used stack: %td\n", stack_base-(void *)&c);  // Estimate of current usage (note that stack usually grows downwards (towards lower addresses)
}

int recursive_call(int n)
{
   int result = 1;
   if(n > 1)
   {
       print_stack_size();
       result = result + recursive_call(n-1);
   }
   return result;
}

int main()
{
    char a;
    stack_base = &a;   // "a" is stored on the stack and at this point we should be close to the top of the stack area
    recursive_call(20);
    return 0;
}

如果编译器的优化不是太激进,这应该显示通过一系列递归函数调用的(近似)堆栈使用情况。
当然,这只给出了给定时间点的快照,但经过一点思考,应该可以找到一些最坏情况的候选者,并了解堆栈的使用情况。在任何情况下,堆栈大小都应该设置为具有健康的边距。

相关问题