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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With