tags:

views:

214

answers:

7

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.

+3  A: 

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
+1  A: 

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
+4  A: 

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(); }
Klark
Be wary of compiler optimizations.
Matt Joiner
@Matt: How would a compiler optimize that? Raise a stackoverflow exception right away??
sbi
@sbi: it might transform the call into a jump.
Hasturkun
@sbi: Noob. I could optimize that by hand, here's the code I would generate:
Matt Joiner
@Matt: I guess you're right. Compilers are likely to not to consider a stack overflow "observable behavior".
sbi
@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
In .net you can raise a stackoverflow exception, not tried with C++.
Behrooz
@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
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
@sbi: Yes, so back to my original point. Don't enable optimizations with the code given by SINTER especially on GCC.
Matt Joiner
@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
+1  A: 

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

UncleZeiv
+1  A: 

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.

Adrian Regan
+3  A: 

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
+1 for the note on STL containers.
PeterK
+0 for recursing deeply
Matt Joiner
@Matt: I have no idea what you're trying to tell me.
sbi
A: 

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