Moh*_*ria 14 c++ stack-overflow
我有下面列出的代码,并在运行时报告堆栈溢出.我使用pass by value来showTest().我期望它会将Test结构的副本复制到堆栈(推送到堆栈),然后在函数调用结束时Test释放结构(弹出堆栈).所以我打三次电话.它应该推入堆栈并在每个函数调用结束时弹出.
如果每次调用函数时它都会按下并弹出堆栈,我看不到任何堆栈问题.但是,当我运行此代码时,它会在第一行报告堆栈溢出异常main.(我使用Visual Studio 2017.)
如果我删除其中一个showTest()函数调用,那么我可以让它工作.
任何反馈都将受到高度赞赏.
#include <iostream>
struct Test
{
static int Userid;
int data[100000] = { };
Test()
{
++Userid;
};
};
int Test::Userid = 0;
void showTest(Test i_myint)
{
std::cout << "test" << std::endl;
}
int main()
{
Test *pint = new Test();
showTest(*pint);
Test *pint2 = new Test();
showTest(*pint2);
Test *pint3 = new Test();
showTest(*pint3);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
n. *_* m. 26
这里明显发生的是延迟堆栈弹出.
在C和C++中,常见的调用约定是调用者从堆栈中弹出参数.作为一种常见的优化,许多编译器在每次调用后都不会弹出参数,但是在多次调用之后执行此操作并将所有累积的参数一起弹出.这节省了一些指令,代价是可能溢出的更大堆栈.
在MSVC中,当禁用优化时,编译器会事先为给定函数中所需的所有调用分配并检查堆栈.这就是程序在打印任何内容之前崩溃的原因.
一些最初的说明main是
mov eax, 1200120 ; 00124ff8H
call __chkstk
sub rsp, rax
Run Code Online (Sandbox Code Playgroud)
这个数字正是在堆栈上拟合三个对象实例所需的数字.
启用优化后,编译器足够智能以重用堆栈,因此不会崩溃.
mov eax, 400032 ; 00061aa0H
call __chkstk
sub rsp, rax
Run Code Online (Sandbox Code Playgroud)
足够单个实例.
| 归档时间: |
|
| 查看次数: |
1875 次 |
| 最近记录: |