Re: Exceeding memory while using STL containers
ThosRTanner wrote:
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.
Well, that isn't always the case. I know one system where the
stack was grown by mallocing extra space from the heap, and
chaining blocks. Worked very nicely, and stack overflow ==
memory exhaustion, not heap corruption.
Recently? I used such a system in the late 1980's (an
unofficial port of C to the Siemens BS2000 mainframes). The
effect on performance pretty much made it unusable -- a couple
of hundred machine instructions for a function call.
On the other hand, all of the HP/UX machines I've seen had a
stack which grew up, not down. The stack had a fixed maximum
size, with the heap (also growing up) directly above it.
I currently work on a platform where the stack grows down,
but is limited to 1gig, and the heap grows up, and is also
limited to 1 gig. This is problematic because we use very
little stack space but lots of heap, and yet we are still
limited to 1 and 1. With a floating separator between stack
and heap, we could get 1.8 and 0.2, which is more like what
we actually need.
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. However, what do you do when the stack
approaches the heap? Is it allowed to throw bad_alloc at
the point when it detects this? If not, what do you do? 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).
It could just terminate, bad_alloc as the result of a call
might cause the runtime system some confusion.
Yes. What usually happens is that the system will maintain some
guard pages between the heap and the stack. When you increase
the stack size, accesses to the new stack may cause page faults,
which the system then handles -- if there's room, and you're
authorized, it will allocate additional pages. Otherwise, it
will terminate the program (signal 11 in Solaris or Linux -- the
same as if you screwed up with a pointer).
My main objection was not to the stack overwriting the heap
(which I expect to be an issue), but the heap overwriting the
stack. This program on the system I am complaining about
int main()
{
while (malloc(1) != NULL) {};
return 0;
}
will crash in malloc, because the heap eventually ends up
overwriting the stack, and some heap chain information gets
overwritten by the function calls involved in actually doing
the malloc.
That's horrible. Heap allocation is controlled, so there is no
excuse for not checking.
--
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! ]