On running out of memory...
Local variables are often not put into memory at all -- they are frequently completely ephemeral things whose lifespan is spent entirely in registers. Even when that doesn't happen, local variables are placed onto the stack, which may be a different part of memory than the one that
new accesses. The same is true of array variables -- ones declared as
int foo[47]; // This goes on the stack, not the heap
Incidentally, this is why on many computers, the declaration
int bigarray[1 << 22]; // I overflow the stack! Haha!
will cause a segmentation fault (because the OS limits how big the stack can be, and this exceeds that limit), whereas
int *bigarray = new int[1 << 22]; // I live on the heap. It's very roomy here
will succeed.
Unless you are doing something very silly -- e.g. allocating lots of large arrays on the stack or
extremely deeply nested function calls each with lots of local state -- you will never run out of memory because you allocated local variables. (Unless you intentionally decreased the amount of stack space your program allocates, or are on a peculiar architecture that likes to have tiny stacks)
Aside from the programming drawbacks of global variables being used in that way, you will often get better performance by having your scalar variables -- or even small to medium sized arrays -- be local variables. If your function needs lots of scratch space and you really are concerned about functions allocating their own memory, you can pass in a buffer as an argument, such as this routine to multiply multi-precision integers:
// result and buffer must be arrays of xwords * ywords elements
void poorly_implemented_high_school_multiply(unsigned long *result, size_t *rwords, const unsigned long *x, size_t xwords, const unsigned long *y, size_t ywords, unsigned long *buffer);