2

This is probably a stupid question, but I am having a hard time finding something online about it.

I know that operator new can throw a bad_alloc exception if it fails to allocate memory, but what happens with local variable allocation?

Imagine I have a system where there is no more memory available and the program executes something like:

void do_something(){
 int a = 0;
}

What will happen? how is the space necessary for "a" allocated? Can it throw?

I got the question from seeing code similar to this somewhere:

void do_something() noexcept {
    // some local variables being allocated
}

It got me wondering the relation between no except and local memory allocation. Also, to make things a bit more confusing I saw this which got me wondering about when the memory allocation actually happens...

Community
  • 1
  • 1
Mac
  • 3,397
  • 3
  • 33
  • 58
  • 1
    I would think this would cause a StackOverflow? Although I've never had it happen to me. – Carcigenicate Apr 21 '17 at 23:50
  • I'm assuming the program would just crash because it can't add memory so it would just throw an error? – Chris Hutchison Apr 21 '17 at 23:52
  • 1
    With modern OS this can't happen because of virtual memory. @CJHutchison – SRIDHARAN Apr 22 '17 at 00:12
  • 1
    @CJHutchison even virtual memory has a limit... – Mac Apr 22 '17 at 00:15
  • 1
    @Sridharan - Of course it can. Stack space in a process is limited, and much less than total virtual memory. – Donnie Apr 22 '17 at 00:39
  • Stack space is typically a tiny fraction of available memory. One isn't expected to use large memory automatic variables. If this is exceeded the program will crash. http://stackoverflow.com/questions/1578878/catching-stack-overflow-exceptions-in-recursive-c-functions – doug Apr 22 '17 at 03:42

3 Answers3

2

I don't think that do_something(){ int a = 0; } can throw. There is no such thing as storage allocated for 'a', in most cases this will be in processor register and you do not know if it even will be stored in memory or not..

Regarding

void do_something() noexcept {

This simply tells compiler that your function do_something cannot throw c++ exceptions, and as a result compiler may make some assumptions and perhaps make some extra optimizations.

Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • In your first case, that would just be optimized out since there's no side effects and it's never used. If it is used, you cannot assume that it'll go into a register. – Donnie Apr 22 '17 at 00:41
  • There is storage for every variable which is not optimized out, which is easy to prevent. I believe that local variables falls into block-scope category, and thus has *automatic storage*. The real question is whether automatic storage allocation can throw or fail. – luk32 Apr 22 '17 at 01:05
  • `void do_something(){ std::vector foo(1000000000000000LL); }` can throw and `foo` is an automatic object. – NathanOliver Apr 22 '17 at 01:57
  • @NathanOliver that's totally different and unrelated to `int a`. – Pavel P Apr 22 '17 at 02:50
  • @NathanOliver The question isn't about whether initialization can throw, but (automatic) allocation. It's easy to show that initializaction can throw by making a constructuctor with `throw`. This `std::vector` throws on dynamic allocation, although it's quite close. – luk32 Apr 22 '17 at 10:56
0

No.

Automatic variables are stored on the stack (don't have to be, but I've never heard about a compiler that implemented that other way AFAIK). Since stack is allocated at runtime, there is no chance of program throwing any alloc error (because it's already allocated.. right?).

Of course error can happen during usage of that local variable, i. e. there can be memory problem on the physical/os level. Although in that case, apropriate signal will be thrown, not an exception.

Outshined
  • 709
  • 7
  • 22
  • 1
    you can have an instance of `std::vector` which is an automatic object but it's construct can throw. Plenty of automatic objects can throw on construction. Now if we are just talking POD objects well that is a different story. – NathanOliver Apr 22 '17 at 01:55
0

To follow up on what you said can happen with operator new, bad_alloc can happen with any dynamically allocated memory. So any pointers, smart pointers, many containers etc. This allocation takes place on heap.

Then there is a stack memory where are non dynamically alocated variables like locals just as the one in your example or any globals or static variables and many other things.

To answer your question, if local variable woul fail to alloc it would probably mean you ran out of stack memory, what is called a stack overflow. If this was the case, throwing an exception isn't an option. When you throw the exception, memory for the object thrown is allocated at stack therefore in that case it would throw as well. In that case what is more likely to happen is that your program just exits.

And to mention points stated in comments, yes, usually initializations like the one in your code gets optimized by the compiler.

Maroš Beťko
  • 2,181
  • 2
  • 16
  • 42