Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would a C++ program allocate more memory for local variables than it would need in the worst case?

Inspired by this question.

Apparently in the following code:

#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if( GetTickCount() > 1 ) {
        char buffer[500 * 1024];
        SecureZeroMemory( buffer, sizeof( buffer ) );
    } else {
        char buffer[700 * 1024];
        SecureZeroMemory( buffer, sizeof( buffer ) );
    }
    return 0;
}

compiled with default stack size (1 megabyte) with Visual C++ 10 with optimizations on (/O2) a stack overflow occurs because the program tries to allocate 1200 kilobytes on stack.

The code above is of course slightly exaggerated to show the problem - uses lots of stack in a rather dumb way. Yet in real scenarios stack size can be smaller (like 256 kilobytes) and there could be more branches with smaller objects that would induce a total allocation size enough to overflow the stack.

That makes no sense. The worst case would be 700 kilobytes - it would be the codepath that constructs the set of local variables with the largest total size along the way. Detecting that path during compilation should not be a problem.

So the compiler produces a program that tries to allocate even more memory than the worst case. According to this answer LLVM does the same.

That could be a deficiency in the compiler or there could be some real reason for doing it this way. I mean maybe I just don't understand something in compilers design that would explain why doing allocation this way is necessary.

Why would the compiler want a program allocate more memory than the code needs in the worst case?

like image 456
sharptooth Avatar asked Aug 17 '11 09:08

sharptooth


People also ask

How local variables are allocated in memory?

The allocation of Local Variables occurs when the calling VI is loaded into memory. If it is a stand-alone VI, then the memory for the Local Variable is allocated at run-time and deallocated at the end of its run.

Are local variables more efficient?

Local variables can be faster because the optimizer can store them in registers. In C++ in general, you can't make a statement about the performance difference.

How are local variables stored in C?

Local (temporary) variables Local variables are declared within a function and are not visible to other functions. address. The address returned points to a variable which is stored on the program stack. unused for the remainder of the program's operation will continue to occupy memory space.

Why are local variables stored in stack?

When a function is called the local variables are stored in a stack, and it is automatically destroyed once returned. A stack is used when a variable is not used outside that function. It allows you to control how memory is allocated and deallocated. Stack automatically cleans up the object.


2 Answers

I can only speculate that this optimization was deemed too unimportant by the compiler designers. Or perhaps, there is some subtle security reason.

BTW, on Windows, stack is reserved in its entirety when the thread starts execution, but is committed on as-needed basis, so you are not really spending much "real" memory even if you reserved a large stack.

Reserving a large stack can be a problem on 32-bit system, where having large number of threads can eat the available address space without really committing much memory. On 64-bit, you are golden.

like image 92
Branko Dimitrijevic Avatar answered Sep 20 '22 12:09

Branko Dimitrijevic


It could be down to your use of SecureZeroMemory. Try replacing it with regular ZeroMemory and see what happens- the MSDN page essentially indicates that SZM has some additional semantics beyond what it's signature implies, and they could be the cause of the bug.

like image 26
Puppy Avatar answered Sep 20 '22 12:09

Puppy