views:

323

answers:

4

If my application is out of memory when i call new() i will get exception and malloc() i will get 0 pointer.

But what if i call a method with some local variables? They occupy memory too. Is there some way to reserve memory for "normal" variables? So that even though new() throws exception i can just catch it, fix stuff and still call methods like usual.

+1  A: 

New allocates memory from the heap, but local vars are normally on the stack - which can overflow, but is less likely, depending on your platform. Can you provide more details?

Jeff
lets say i call new or malloc until they fail because there is no more memory left.Then i call some method which has lets say 100 local integer variableswhat happens? I need the method to work as usual.
Michael
The heap and the stack are two separate memory areas - not usually related. You could have a 2Mb heap, and a 1Mb stack.
Jeff
@Jeff: I don't if it's the same in modern protected mode OSes, but back in the DOS days, stack and heap could collide -- basically, the stack grew down from the top of memory, and the heap grew up.
j_random_hacker
@j_random_hacker: Agree - "back in the day" - we could accidentally or deliberately run them together. The kids these days have it easy!Embedded systems still have issues -
Jeff
+3  A: 

THe C++ language doesn't provide any mechanism for reserving memory for local variables. Your specific C++ implementation and/or operating system may provide some means of increasing the total stack size, but this is not normally necessary.

Note also that if a call to new does fail, there is probably very little you can practically do to recover from it. Many people (me included) no longer bother checking for new failure.

anon
Re new failure: one issue is that the exception handler/logging logic might try to allocate room on the heap -- which of course will fail! To lower the chances of this "nested error," you can allocate a small "parachute" at the start of the program (e.g. 2kb) and delete this upon new failure.
j_random_hacker
(Of course most people would know not to call new directly in an error handler that could be called on out-of-memory... But new could be called indirectly, e.g. by std::vector<>, and it's harder to eliminate this possibility.)
j_random_hacker
+1  A: 

The compiler knows how much of memory per stack you need. However, sufficiently high number of stacks (caused due to recursion) will crash your program -- there probably isn't another way to fix this.

The standard has an interesting annexure called Implementation Quantities. This is non-normative (informative) and hence should not be treated as the absolute truth, but provides you with a fair idea.

dirkgently
but will it reserve enough memory for at least SOME number of stacks?
Michael
Yes, it may. A self-respecting compiler will also try to fix tail recursion and other atrocities to the best of its knowledge (and with a little help from you). A nice way to check this is to write a fibonacci and call it for say a value like 600.
dirkgently
When you say "memory per stack" you are talking about stack frames, which the compiler does know. The total stack size required by a program is dependent on the code path, so is normally very hard (if not impossible) for a compiler to predict. Normally the programmer would indicate the stack size required for a program (or thread, for that matter)
Jeff
@Jeff: I meant both stack housekeeping memory + variables.
dirkgently
@Jeff: But good points.
dirkgently
There is generally only one stack, and it is used for both housekeeping and local variables. (all of which fits into one stack frame for each function call). And generally, the stack size is fixed (1mb is a common default value, afaik)
jalf
+5  A: 

Your data is allocated in one of three ways:

  • Statically allocated data (static members or globals) are allocated when the app starts up, which means that they're not really going to be a problem.
  • Stack allocated data is allocated on the stack (surprise!) The stack is an area of memory that's set aside for local variables and function stackframes. If you run out of space there, it's undefined what happens. Some implementations might detect it and give you an access violation/segmentation fault, and others will just make you overwrite heap data. In any case, there's no way to detect this, because in general, there's no way to handle it. If you run out of stack space, there's just nothing you can do. You can't even call a function, because that takes up stack space.
  • Heap allocated memory is what you use when you call new/malloc. Here, you have a mechanism to detect out-of-memory situations, because you may be able to handle it. (Instead of allocating 200mb, you might be able to make do with 100mb, and just swap the data out halfway through)

You generally shouldn't run out of stack space unless you perform some heavy recursion though.

jalf