Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stack Overflow: Duplicate temporary allocation in stack space?

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;
}

Program received signal SIGSEGV, Segmentation fault. 0x08048510 in foo (step=4000) at t.cpp:12 12 void foo(int step = 0) {

It seems that the MemBlock() instance costs a lot of stack memory though it hasn't been called yet (check gdb info).

And when I use global = global * global instead, the program exits normally.

Can anybody explain the inner mechanism?

like image 832
Determinant Avatar asked Jul 20 '12 12:07

Determinant


1 Answers

The compiler is reserving the stack space for the MemBlock instance on each call to foo, regardless of the control flow within foo. This is a common optimisation to prevent having to repeatedly adjust the stack pointer within the function. Instead, the compiler calculates the maximum stack space required and on entry to the function adjusts the stack pointer by that amount.

As you've observed, this results in losing stack space reserved for objects you don't actually use. The answer is to not do that; if you're only using some large-footprint objects within certain branches then separate those branches out into their own function.

Incidentally, this is why archaic versions of C required all function-scope variables to be declared at the top of the function; so that the compiler can easily work out how much stack space the function requires.

like image 70
ecatmur Avatar answered Nov 02 '22 11:11

ecatmur