Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is total stack size required by a function and variable scope related?

I'm getting a stack overflow in my program being compiled with Visual Studio 2010. I have a macro that, within a do-while block, does some string related work using a small char array allocated on stack (8 KiB). I then have a function where I use this macro many times in the same scope. And now I'm getting stack overflows.

I was assuming that the stack allocation was local to the do-while block, and thus when the block ended the array would cease to exist and thus not contribute to the overall stack usage of the function, but it appears I was wrong.

Using the debugger I was able to see that upon entering the function, _chkstk() is called. As an argument to this function is a stack size slightly larger than the sum of all the 8 KiB arrays from each invocation of the macro in that function (slightly larger due to other local variables).

I have recreated the problem using a simple example:

void func(void)
{
    {char a[500000];}
    {char b[500000];}
    {char c[500000];}
    {char d[500000];}
    {char e[500000];}
}

In a simple console application calling this function from main() will result in a stack overflow. Removing all but one of the block statements will however run just fine.

I am wondering if this is working as intended?

How is total stack size required by a function calculated? How is stack size required by a function calculated? Arrays on stack still contribute to total stack size of function, even after going out of scope?

Why am I getting a stack overflow when

like image 293
user2373744 Avatar asked May 11 '13 21:05

user2373744


People also ask

How do you find the stack size of a function?

Count the number of complete strings, multiply by 8 (since "STACK---" is 8 bytes long), and you have the number of bytes of remaining stack space.

What is the maximum size of stack growth of your algorithm?

In Visual Studio the default stack size is 1 MB i think, so with a recursion depth of 10,000 each stack frame can be at most ~100 bytes which should be sufficient for a DFS algorithm. Most compilers including Visual Studio let you specify the stack size.

What is the stack size?

Stack contains all local variables & data, intermediate storage for registers, and function parameters. A typical stack is an area of computer memory with a fixed origin and a variable size. Initially the size of the stack is zero.

How is stack allocated?

Stack Allocation: The allocation happens on contiguous blocks of memory. We call it a stack memory allocation because the allocation happens in the function call stack. The size of memory to be allocated is known to the compiler and whenever a function is called, its variables get memory allocated on the stack.


1 Answers

I'm pretty sure that the standard doesn't define exactly how much space on the stack (or indeed that they are stored on the stack) these variables require. The compiler is certainly not required to NOT allocate a space for each of these local variables. The actual reuse may also be highy dependent on the optimization levels of the compiler - so it may do different things if you compile with different levels of optimization (or if you enable/disable certain optimization features).

In C++, the calls to constructors and destructors are defined for blocks which enclose the variable, so if you were to use std::vector, the memory (allocated from the heap) is released when the block ends.

In summary: The space MAY be reused, but it's by no means guaranteed.

like image 84
Mats Petersson Avatar answered Sep 22 '22 16:09

Mats Petersson