Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 堆栈溢出:是否在堆栈空间中重复临时分配?_C++_Stack Overflow - Fatal编程技术网

C++ 堆栈溢出:是否在堆栈空间中重复临时分配?

C++ 堆栈溢出:是否在堆栈空间中重复临时分配?,c++,stack-overflow,C++,Stack Overflow,程序接收信号SIGSEGV,分段故障。 t.cpp:12时,foo中的0x08048510(阶跃=4000) 12无效foo(整数步长=0){ MemBlock()实例似乎消耗了大量堆栈内存,尽管它还没有被调用(请检查gdb info) 当我使用global=global*global时,程序会正常退出 有人能解释一下内部机制吗?编译器在每次调用foo时都会为MemBlock实例保留堆栈空间,而不管foo中的控制流如何。这是一种常见的优化方法,可以防止在函数中重复调整堆栈指针。相反,编译器ler

程序接收信号SIGSEGV,分段故障。 t.cpp:12时,foo中的0x08048510(阶跃=4000) 12无效foo(整数步长=0){

MemBlock()实例似乎消耗了大量堆栈内存,尽管它还没有被调用(请检查gdb info)

当我使用
global=global*global
时,程序会正常退出


有人能解释一下内部机制吗?

编译器在每次调用
foo
时都会为
MemBlock
实例保留堆栈空间,而不管
foo
中的控制流如何。这是一种常见的优化方法,可以防止在函数中重复调整堆栈指针。相反,编译器ler计算所需的最大堆栈空间,并在输入函数时按该值调整堆栈指针

正如您所观察到的,这会导致丢失为您实际不使用的对象保留的堆栈空间。答案是不要这样做;如果您只在某些分支中使用一些较大的封装外形对象,则将这些分支分离为它们自己的函数


顺便说一句,这就是为什么C的古老版本要求在函数顶部声明所有函数作用域变量的原因;这样编译器就可以很容易地计算出函数需要多少堆栈空间。

您收到SEGFULT,因为您递归调用foo 10000次,它与MemBlock无关class@TomKnapen,不,你错了。a)4001给我打电话时它就死了。b)如果你删除
if
里面的东西,它就不会死。@SingerOfTheFall我的评论在读到“尝试调用foo 10000次”时可能更好,但重点是:这是递归的错误。如果你删除if块,编译器可能会优化f函数调用,从而删除递归。您可能希望添加
int*test=&step
变量,并观察调用堆栈上的不同值。我敢打赌这显示了调试器中分配的实际堆栈内存。我喜欢最后的历史课,我不知道这一点:)我试图用
MemBloc替换表达式k*t=new MemBlock;global=global**t;
我以为它会在运行时构建,不会影响堆栈空间。但仍然是错误的。问题是什么?+1表示“如果您只在某些分支中使用一些较大的封装外形对象,那么将这些分支分离到它们自己的函数中。”…和顺便提一下,这就是为什么C的古老版本要求在函数顶部声明所有函数作用域变量的原因;这样编译器就可以轻松计算出函数需要多少堆栈空间“@ymfoi在这种情况下,编译器为表达式
global**t
的返回值保留堆栈空间!@ecatmur抱歉,我不太明白。什么是“返回值”?
struct MemBlock {

    char mem[1024];

    MemBlock operator*(const MemBlock &b) const {

        return MemBlock();
    }

} global;

void foo(int step = 0) {

    if (step == 10000)
    {
        global = global * MemBlock();
    }
    else foo(step + 1);
}

int main() {

    foo();
    return 0;
}