Handling allocation failures?

R

Richard Tobin

Consider the following facts:
1) An mpz_t can store an integer of arbitrarily large size.
2) By the Pidgeon Hole Principal, setting an mpz_t can therefore take up
an arbirarily large amount of memory.
3) But the mpz_set_... functions all return voids, and the documentation
doesn't mention anything about them indicating an allocation failure in
some other way besides the return value.
4) Therefore there is no way for the user of the library to diagnose and
attempt to recover from allocation failure.
5) This is quite shoddy in a library intended for public use.

Ints have the same problem. A C program may run out of stack space,
and C doesn't provide any way to detect it. Whether this is a problem
depends on your application.

-- Richard
 
R

root

Consider the following facts:
1) An mpz_t can store an integer of arbitrarily large size.
2) By the Pidgeon Hole Principal, setting an mpz_t can therefore take up
an arbirarily large amount of memory.
3) But the mpz_set_... functions all return voids, and the documentation
doesn't mention anything about them indicating an allocation failure in
some other way besides the return value.
4) Therefore there is no way for the user of the library to diagnose and
attempt to recover from allocation failure.
5) This is quite shoddy in a library intended for public use.

Is this argument right?
 
S

santosh

root said:
Consider the following facts:
1) An mpz_t can store an integer of arbitrarily large size.
2) By the Pidgeon Hole Principal, setting an mpz_t can therefore take up
an arbirarily large amount of memory.
3) But the mpz_set_... functions all return voids, and the documentation
doesn't mention anything about them indicating an allocation failure in
some other way besides the return value.
4) Therefore there is no way for the user of the library to diagnose and
attempt to recover from allocation failure.
5) This is quite shoddy in a library intended for public use.

Is this argument right?

You should probably address your criticism of the library to a GMP mailing
list. This has nothing to do with ISO C. At a minimum you might take your
library design discussion to a more general programming group like
comp.programming.
 
R

root

You should probably address your criticism of the library to a GMP mailing
list. This has nothing to do with ISO C. At a minimum you might take your
library design discussion to a more general programming group like
comp.programming.

Well, GMP was just an example: really I'm asking for views on whether
ignoring allocation failures is ever acceptable for a library.

I ask because I'm designing a library at the moment. There's a struct
type that has a couple integer fields and a couple pointer fields.
There's a mystruct_init() function that populates the fields, including
making the pointers point to something dynamically allocated.

So what to do if malloc() fails? It's a library, so printing an error
(or still worse abort()ing) is out of the question. One possibility is
to ask the caller to check each of the pointers inside the struct to see
whether they're NULL each time it inits() a mystruct. But that doesn't
seem very friendly, and various mystruct_...() functions might realloc()
the pointers so this would become complex for calling code and generally
scale badly.

The situation seems comparable to mpz_t, in that although in theory the
amount of memory needed could be very large, in practise it will almost
always only be perhaps enough for a couple dozen pointers-to-int. So if
GMP can get away with ignoring allocation failure, maybe I can too - is
what I was thinking/hoping.
 
J

jacob navia

root said:
Well, GMP was just an example: really I'm asking for views on whether
ignoring allocation failures is ever acceptable for a library.

I ask because I'm designing a library at the moment. There's a struct
type that has a couple integer fields and a couple pointer fields.
There's a mystruct_init() function that populates the fields, including
making the pointers point to something dynamically allocated.

So what to do if malloc() fails? It's a library, so printing an error
(or still worse abort()ing) is out of the question. One possibility is
to ask the caller to check each of the pointers inside the struct to see
whether they're NULL each time it inits() a mystruct. But that doesn't
seem very friendly, and various mystruct_...() functions might realloc()
the pointers so this would become complex for calling code and generally
scale badly.

The situation seems comparable to mpz_t, in that although in theory the
amount of memory needed could be very large, in practise it will almost
always only be perhaps enough for a couple dozen pointers-to-int. So if
GMP can get away with ignoring allocation failure, maybe I can too - is
what I was thinking/hoping.

One alternative is to establish a global function pointer that points to
a function to call in case of error.

The user of your library can establish a function of its own if he/she
wishes, and you provide a default function. That default function could
establish a global flag that will make calls to the library impossible,
or similar measures.

This allows for an error handling without having to check each time

jacob
 
F

fred.l.kleinschmidt

Well, GMP was just an example: really I'm asking for views on whether
ignoring allocation failures is ever acceptable for a library.

I ask because I'm designing a library at the moment. There's a struct
type that has a couple integer fields and a couple pointer fields.
There's a mystruct_init() function that populates the fields, including
making the pointers point to something dynamically allocated.

So what to do if malloc() fails? It's a library, so printing an error
(or still worse abort()ing) is out of the question. One possibility is
to ask the caller to check each of the pointers inside the struct to see
whether they're NULL each time it inits() a mystruct. But that doesn't
seem very friendly, and various mystruct_...() functions might realloc()
the pointers so this would become complex for calling code and generally
scale badly.

The situation seems comparable to mpz_t, in that although in theory the
amount of memory needed could be very large, in practise it will almost
always only be perhaps enough for a couple dozen pointers-to-int. So if
GMP can get away with ignoring allocation failure, maybe I can too - is
what I was thinking/hoping

One way could be:

MyStruct mystruct;
/* or *mystruct, if mystruct_init() also allocates the struct) &/

int mystruct_init( &mystruct );

where the return value is 0 in success, and a macro-defined value
indicating an error. You can #define many such error codes, so the
calling function can determine what error occurred and act
accordingly.
 
R

Richard Heathfield

root said:

really I'm asking for views on whether
ignoring allocation failures is ever acceptable for a library.

As ever, it depends - but to ignore failures would not endear a library to
me. It's a massive weakness, which would have to be balanced by astounding
strengths in other areas that could not otherwise have been achieved.

So what to do if malloc() fails? It's a library, so printing an error
(or still worse abort()ing) is out of the question.

Agreed - but you can report the error to the caller. A simple int would
suffice. There are a number of corrective actions a caller might take to
make more memory available, after which you may get the chance to have
another stab at acquiring the necessary memory.

<snip>
 
M

Malcolm McLean

root said:
I ask because I'm designing a library at the moment. There's a struct
type that has a couple integer fields and a couple pointer fields.
There's a mystruct_init() function that populates the fields, including
making the pointers point to something dynamically allocated.

So what to do if malloc() fails? It's a library, so printing an error
(or still worse abort()ing) is out of the question. One possibility is
to ask the caller to check each of the pointers inside the struct to see
whether they're NULL each time it inits() a mystruct. But that doesn't
seem very friendly, and various mystruct_...() functions might realloc()
the pointers so this would become complex for calling code and generally
scale badly.

The situation seems comparable to mpz_t, in that although in theory the
amount of memory needed could be very large, in practise it will almost
always only be perhaps enough for a couple dozen pointers-to-int. So if
GMP can get away with ignoring allocation failure, maybe I can too - is
what I was thinking/hoping.
There's no easy answer.
The default should be to return a NULL pointer or similar failure to the
caller. This has the disadvantage that the program is stuffed with
error-handling code that will never be called.

If the amount of memory asked for is small you've got to ask "how likely is
a failure" and "what does a failure mean?". If, for instance, the chance of
an allocation failure is statisitically less than the chance of the computer
breaking down, you could argue that you are justified in ignoring it. If
realistically the program cannot continue if the system is refusing to give
it a few bytes, you could argue that you might as well terminate now rather
than in calling code.

The problem is that often callers do want to recover from errors, for
instance permitting the user to save. That raises a whole host of other
issues - often it is better not to save at all rather than save a corrupt
state - but as library writer you cannot handle them.

The other alternative is to write a wrapper to malloc() that never fails. If
memory is exhausted, it asks the user for more memory, looping until user
either complies or takes other action against the program. The snag is that
C has no usable user IO to make this function practical to be written
portably, unless you allow the caller to specify a nag function. That adds a
lot of complexity to your library interface.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top