4

I know that by using operator new() I can exhaust memory and I know how to protect myself against such a case, but can I exhaust memory by creating objects on stack? And if yes, how can I check if object creation was succesful?
Thank you.

There is nothing we can do
  • 23,727
  • 30
  • 106
  • 194
  • 18
    'Stack overflow' – Tim Robinson Jul 27 '10 at 09:56
  • @All Thanks for your answers. But have seen them all there is no answer how to prevent(check) so do I assume that there is no way to do that? – There is nothing we can do Jul 27 '10 at 10:10
  • As far as i know, no there is no way. You can however make sure that this does not happen. That is the best thing to do. Also you could make the stack bigger (your compiler should have some options how to set stack size). – PeterK Jul 27 '10 at 10:16
  • Check this: http://stackoverflow.com/questions/1373686/unable-to-catch-c-exception-using-catch – Klark Jul 27 '10 at 10:20
  • 1
    ha: I believe that both of the questions you asked have been answered: *Can I exhaust memory by creating objects on stack?* **Yes**, *how can I check if object creation was succesful?* **The program has not crashed** Then you added a third question as a comment: *how to prevent it?* Few times in common programs you encounter the problem and it is not related to a bug (infinite recursion), if you need more stack memory, use your OS facilities to provide for it, or else move the biggest objects from the stack to heap memory. – David Rodríguez - dribeas Jul 27 '10 at 10:38

7 Answers7

4

You can exhaust a stack. In such cases, your program will probably crash with the stack overflow exception immediately.

A stack has a size too, so you can look at it as simply a block of memory. Variables inside functions for example are allocated here. Also when you call a function, the call itself is stored on the stack (very simplified, i know). So if you make a infinite recursion (as mentioned in another answer) then the stack gets filled but not emptied (this happens when a function returns, the information about the call is "deleted") so at some time you will fill the whole space allocated for your programs stack and your app will crash.

Note that there are ways how to determine/change the size of stack.

PeterK
  • 6,287
  • 5
  • 50
  • 86
4

Just look at the title of this site and you will see the answer. Write some infinite recursion if you want to see "live" what happens.

i.e.

void fun() { fun(); }
Matt Joiner
  • 112,946
  • 110
  • 377
  • 526
Klark
  • 8,162
  • 3
  • 37
  • 61
  • 5
    Be wary of compiler optimizations. – Matt Joiner Jul 27 '10 at 10:00
  • 4
    @Matt: How would a compiler optimize that? Raise a stackoverflow exception right away?? – sbi Jul 27 '10 at 10:13
  • 1
    @sbi: it might transform the call into a jump. – Hasturkun Jul 27 '10 at 12:09
  • @sbi: Noob. I could optimize that by hand, here's the code I would generate: – Matt Joiner Jul 27 '10 at 14:06
  • @Matt: I guess you're right. Compilers are likely to not to consider a stack overflow "observable behavior". – sbi Jul 27 '10 at 14:18
  • @sbi: A good compiler would optimize that function to nothing. Not even a nop, it has no effect. Compilers don't optimize towards goals, they just cut the fat along the way. A compiler isn't going to know you're attempting to exhaust all your memory, so it isn't going to raise a stackoverflow exception to save time. I might add that I don't think a compiler *could* put in code to raise SO exception anyway, that's an OS thing. – Matt Joiner Jul 27 '10 at 14:47
  • In .net you can raise a stackoverflow exception, not tried with C++. – Behrooz Jul 27 '10 at 14:57
  • 2
    @Matt: In C++, it is an OS thing, in other languages (e.g., C#) not. Limiting the discussion to C++: With very few exceptions (like omitting calls to copy ctors), C++ compilers are allowed to optimize the code _as long as the observable behavior is the same_ as with the unoptimized code. That's why the question whether compilers would attempt to reproduce the SO during optimizing boils down to: _Is a SO considered "observable behavior"?_ I think it probably is _not_, which is why, contrary to my first comment, I agree with you that a compiler shouldn't attempt to reproduce it while optimizing. – sbi Jul 27 '10 at 15:11
  • I missed the part where C# was an example of anything at all except as a proprietary nightmare, let alone a question tagged C++. – Matt Joiner Jul 28 '10 at 02:10
  • @sbi: Yes, so back to my original point. Don't enable optimizations with the code given by SINTER especially on GCC. – Matt Joiner Jul 28 '10 at 02:11
  • @Matt: Again, I have no idea what you are trying to tell me. I was limiting the discussion to C++, I explained why I think the term "observable behavior" is important in this context, I said I agree with you wrt the outcome of optimizations, and why I do so. (The code given by SINTER will exhaust the stack, thereby invoking undefined behavior. There is no guarantee for what optimization will turn in it, although, as I said, IMO the outcome is likely what you predicted.) – sbi Jul 28 '10 at 06:52
3

Yes, you can exhaust the stack. On common systems, the hardware/OS traps that and aborts your program. However, it is hard to do so. You would have to either create huge objects on the stack (automatic arrays) or do deep recursion.

Note that, if you use common abstractions such as std::string, std::vector etc., you can hardly ever exhaust the stack, because while they live on the stack, they have their data on the heap. (This is true for all STL containers coming with the std lib except for std::tr1::array.)

sbi
  • 219,715
  • 46
  • 258
  • 445
1

Yes, see the site's name. You can't really check that the object creation is successful -- the program simply crashes on stack overflow.

Amnon
  • 7,652
  • 2
  • 26
  • 34
1

Memory is not infinite, so wherever you allocate objects you will eventually run out of it.

UncleZeiv
  • 18,272
  • 7
  • 49
  • 77
1

Ok, but you'll need sharp reactions to spot when the 'object creation' succeeds.

class MyObject {
private:
   int x
public:
   MyObject() { x = 0; }
};

int main(int argc, char **argv) {
    IWantToExhaustTheStack();
    return 0;
}

void IWantToExhaustTheStack() {
    MyObject o;
    IWantToExhaustTheStack();
}

Now compile and run this, for a very short while your object creation will work. You will know that the object creation has failed, when your program fails.

Joking aside, and in response to your updated question, there is no standard way to determine the stack size. See : This Stackoverflow Question in relation to Win32. However, the stack is used to call methods and hold local temporary and return variables. If you are allocating large objects on the stack, you really should be thinking of putting them on the heap.

Community
  • 1
  • 1
Adrian Regan
  • 2,240
  • 13
  • 11
0

Yes, you can exhaust the stack and you cannot test whether object creation fails because after failure this is already too late.

Generally, the only way to protect from stack overflow is to design application in a such way that it will not exceed given limit. I.e. if recursion modifies an image then put limit on image size or use other algorithm for huge images.

Watch recursions (not too deep), watch alloca (not too much). Watch peeks when examining stack usage.

In OpenSolaris there is few functions that lets you to control the stack.

adf88
  • 4,277
  • 1
  • 23
  • 21