Re: memory leak in the code?
On Jan 5, 5:38 pm, kwikius <a...@servocomm.freeserve.co.uk> wrote:
On Jan 5, 3:04 pm, George2 <george4acade...@yahoo.com> wrote:
However if looked at from a practical viewpoint. In case of
bad_alloc the most likely cause is that the system has run out
of memory.
As a result of 1) your application using too much memory in
handling a specific request---in which case, you can return an
error (e.g. insufficient resources) for the request, and still
continue to operate, or 2) your application leaks memory---in
which case, you really do need to get out of there, as quickly
as possible, because the situation isn't going to get any better
anytime soon.
Firstly It is a reasonable idea to try to detect bad_alloc
exceptions.
The problem then is once detected, what to do about them?
In the first case, above, you respond with an error to the
request, saying that you can't handle it.
Whether such cases are plausible or not depends a lot on the
application. I've worked on servers in which "requests" had a
more or less open structure (e.g. represented an arbitrary
expression, usually in some variant of RPN)---LDAP comes to
mind. In such cases, you don't want to abort the server just
because some client goes overboard with his search criteria in
one particular request. (But I'll admit that the case is pretty
special, and probably doesn't apply to most applications. Also,
if you find yourself in such a case, you'll have to work out
something to avoid stack overflow as well.)
Its certainly useful (IMO essential, at least polite) to try
to report this to the user, for which you need to catch the
exception,
Interesting. I've always replaced the new_handler.
If you replace the new_handler, then operator new will
effectively become a nothrow (provided the constructor of the
object cannot throw for other reasons). This can be useful in
certain situations.
Of course, if you replace the new_handler, then such an error
won't cause the destructors on the stack to be called. Which
may be a problem as well. I tend to organize things so that it
won't be a problem, as much as possible, because there are other
cases where they won't be called either (e.g. if you core dump).
Such cases are all probably errors, but then, if you get a
bad_alloc because the program leaks memory, that's a programming
error as well.
(I'm not saying that the points you're raising aren't valid.
Only that there are a lot of things that have to be considered,
depending on the actual application.)
But bear in mind that you are equivalent to the drowning man
in the flooded room gulping the last bit of air, IOW you don't
want to even attempt any more heap allocations if at all
possible, but pretty much anything you do to output a
diagnostic to the user may request allocations.
Referring to my two situations in the first paragraph I wrote:
In case 1, the stack walk back due to the exception will free up
all of the memory the request allocated, so by the time you
catch the exception, there should be no real problem. In case
2: I've always pre-allocated any memory that might be needed to
output such critical error messages before starting operation,
just to be sure that it was there if the case occured.
Neveretheless in this sitaution things can't get much worse,
so you should probably try doing the diagnostic (by calling
some code designed for this particular situation) and quit the
application if thats acceptable.
The point of this is...
If that's the strategy, you adopt then any dangling pointers
will be cleaned up by the system so its not worth worrying
about them in practise. Its also simple. You have done the
right thing by the user. Its their problem now.
You have very tolerant users. If my server goes down, even if
the reason is due to bad_alloc, my users complain to me. (In a
number of cases, there have even been conventional penalties for
down time.)
If that strategy is unacceptable and you hope to continue the app,
then you are into a much more complicated ballgame. You have to find
some way to have some scratch space so you can then set about trying
the complicated task of regaining a useful amount of heap, and you
will need to deal with raw pointers owning heap real estate such as
'a'.
You have to know why you ran out of memory. If the only
possible reason for running out of memory is a memory leak in
your code (a frequent case in the context I work, where the
server, once written, runs on a dedicated machine with no other
applications on it), then of course, continuing is out of the
question. If the reason is that you've received a request that
required too many resources, the problem is handled
automatically by aborting the request.
Another answer is. Dont use new, at least not in functions. If
at all possible allocate in class constructors and release in
destructors. (RAII) Then you will find that the problem is
dealt with automatically, because the destructor for the class
allocated on the stack is called automatically when an
exception is thrown. This is how most std::library types work
under the hood (std::string , containers etc
Smart pointers are another option rather than raw pointers.
If it's only memory you're worried about, garbage collection is
the easiest solution. The same issues arise for other
resources, however, or even just issues of system coherence
(transactional integrity).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34