Re: Exceeding memory while using STL containers
Joshua Lehrer wrote:
ThosRTanner wrote:
Note: I've come across one implementation of C++ where,
given certain memory constraints, when the computer runs out
of memory, your heap overwrites your stack. This is from
people who should have known better. But they won't change
it because apparently speed is more important than correct
and predictable functioning of a program.
This is the way that, in college, I was taught that computers
are supposed to 'work'. The stack grows up, the heap grows
down, and when they meet, you are in trouble.
The question is whether you recognize it or not. Back in the
older days of 64 KB of unprotected memory, it wasn't uncommon
for stack overflow to just overwrite a few variables -- they
actual error didn't occur until much later, and it wasn't always
apparent what caused the error.
With pthread_attr_setstack, you can guarantee this sort of
behavior today; I wouldn't be surprised if even without
pthread_attr_setstack, you can get this behavior in some
threading implementations.
I guess another solution would have the heap and stack growing
toward eachother. If the heap ever needed to grow and it
detected it was too close to the stack, it would throw
bad_alloc.
I think many modern Unixes do this. (Solaris does, at least. I
think Linux on PC does as well.)
However, what do you do when the stack approaches the heap?
Core dumps. At least on every system I've worked on for the
last 15 years.
In practice (although I don't think it is written down
anywhere), once memory has been allocated to the stack, at least
under Solaris (and I'm pretty sure PC-Linux), it is allocated
eternally to the stack. In critical applications, we usually
recurse pretty deeply at start up, in order to allocate the
maximum that will ever been needed; having done this, we will
never run out of stack later. (As far as I know, this is not
explicitly guaranteed anywhere. But I've yet to find a Unix
system where it didn't work.)
Is it allowed to throw bad_alloc at the point when it detects
this?
It is; it can do anything it damn well pleases, since running
out of resources is undefined behavior. But I don't think many
of us would like that; in order to write exception safe code,
you need a few critical functions which cannot throw. If stack
overflow raises an exception, by definition, any function call
can throw.
If not, what do you do?
Cross your fingers? Pray?
Seriously, the only solution I know is to determine the maximum
amount of stack you need (which is far from simple, and requires
a pretty good familiarity with the system architecture and
calling conventions), and pre-allocate it up front, as described
above.
If so, isn't this a lot of overhead to calculate each time you
need to grow the stack? Growing the stack is supposed to be
fast and cheap (usually just an add).
Well, it's never just an add, since you also have to set up the
new stack frame. The trick is to identify the critical spots
(say, before recursing), and only check there. Manually, by
comparing to the top you saved when you recursed to allocate it
in the first place.
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]