Question

Maybe a naive question, but...

Confirm or deny:

The existence of memory for objects/variables of automatic and static storage duration is determined compile-time and there is absolutely zero chance that the program will fail runtime because there wasn't enough memory for an automatic object.

Naturally, when the constructor of an automatic object performs dynamic allocations and such allocation fails, we consider this to be a failure on dynamic allocation, and not automatic.

Was it helpful?

Solution

Two words : Stack Overflow. :P

OTHER TIPS

Automatic allocation can certainly fail - this is usually known as a stack overflow. You see this quite often when someone tries to have a vary large array as a local variable. Unbounded (or not-bounded-enough) recursion can also cause this.

What you can't really do in a platform independent way is detect automatic allocation failure and handle it.

On systems with overcommit (e.g. Linux in the default configuration), it's even possible for objects of static storage duration to result in failure at runtime. At program startup, these objects will exist in either copy-on-write zero-pages (if they were uninitialized) or copy-on-write mappings of the on-disk executable file. Upon the first attempt to write to them, a page fault will happen and the kernel will make a local modifiable copy for your process. If the kernel was careless and did not reserve as much memory as it committed to the process, this could fail, and the result will be the dreaded OOM-killer.

No robust system has this problem, and the Linux behavior can be fixed by:

echo "2" > /proc/sys/vm/overcommit_memory

Not true. An automatic allocation can cause a stack overflow, which causes instant process termination on most architectures/platforms of which I am aware.

Also, it's possible the program cannot allocate enough space for your static variables from the underlying platform, in which case the program will still fail, but it will fail before main is called.

Simple counterexample:

#include <string.h>

int main()
{
    int huge[0x1FFFFFFF]; // Specific size doesn't matter;
                          // it just has to be bigger than the stack.

    memset(huge, 0, sizeof(huge) / sizeof(int));

    return 0;
}

Example:

#include <iostream>

using namespace std;

class A
{
public:
    A() { p = new int[0xFFFFFFFF]; }

private:
    int* p;
};

static A g_a;

int main()
{
    cout << "Why do I never get called?" << endl;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top