函数所需的总堆栈大小如何与变量作用域相关
How is total stack size required by a function and variable scope related?
我得到一个堆栈溢出在我的程序正在与Visual Studio 2010编译。我有一个宏,在do-while块内,使用堆栈上分配的小字符数组(8 KiB)做一些字符串相关的工作。然后我有一个函数,我在同一个作用域中多次使用这个宏。现在我得到堆栈溢出
我假设堆栈分配是do-while块的局部,因此当块结束时,数组将不再存在,因此不会对函数的整体堆栈使用做出贡献,但似乎我错了。
使用调试器,我能够看到在输入函数时,_chkstk()被调用。作为该函数的参数,堆栈大小略大于该函数中每次宏调用的所有8个KiB数组的总和(由于其他局部变量的影响,堆栈大小略大)。
我用一个简单的例子重现了这个问题:
void func(void)
{
{char a[500000];}
{char b[500000];}
{char c[500000];}
{char d[500000];}
{char e[500000];}
}
在一个简单的控制台应用程序中,从main()调用这个函数将导致堆栈溢出。然而,删除除一条语句外的所有块语句将正常运行。
我想知道这是否按预期工作?
如何计算函数所需的总堆栈大小?如何计算函数所需的堆栈大小?堆栈上的数组仍然对函数的总堆栈大小有贡献,即使在超出作用域之后?
为什么当
我很确定标准没有确切定义这些变量需要多少堆栈空间(或者实际上它们存储在堆栈上)。编译器当然不需要为每个局部变量分配空间。实际的重用也可能高度依赖于编译器的优化级别——因此,如果使用不同级别的优化进行编译(或者启用/禁用某些优化特性),它可能会做不同的事情。
在c++中,对构造函数和析构函数的调用是为包含变量的块定义的,因此如果您要使用std::vector
,则在块结束时释放内存(从堆中分配)。
总而言之:空间可以被重用,但这并不能保证。
我想这是特定于编译器的。在GCC中也可以很好地工作:数组在超出作用域后从堆栈中删除(但是当所有数组属于同一块时,它会抛出段错误)。
- 在类函数中初始化外部作用域变量
- 不同作用域中的静态变量和全局变量
- 未在此作用域中声明的函数和变量 (C++)
- 如何在C++中访问作用域的变量输出?
- 不同块作用域中的 C++ 变量具有相同的地址
- C++If语句变量作用域
- 派生类变量作用域 c++
- 如何理解C++变量作用域规则
- C/C++编译器关于变量作用域的优化
- 应用程序有2个静态变量作用域
- 堆变量作用域
- c++中变量作用域的机制
- c++变量作用域的类友
- 函数所需的总堆栈大小如何与变量作用域相关
- 声明友元函数时出现变量作用域错误
- 引用的C++变量作用域
- c++中的变量作用域
- c/c++中局部变量作用域和生命周期的混淆
- c++中的局部/静态变量作用域
- 多个c++文件和变量作用域