P
Philip Pemberton
Hi,
I'm currently playing around with a little spam filter for my Linksys NSLU2
(I would have used Spamassassin but that's slow even on my 2GHz Athlon64 - on
a 266MHz XScale it's likely to be intolerably slow). As part of that, I'm
keeping track of the DNSBL blocklists that are being queried using a
dynamically-allocated array.
When a new DNSBL zone is added to the zone array, I use realloc() to
increase the amount of memory available for the array. The newly-allocated
block then gets filled in with the zone's details, and a null block (one where
the "zone" pointer is set to NULL) is stored to act as a terminator.
At the moment, I'm using code like this:
if ((zones = realloc(zones, (zonecount + 2) * sizeof(ZONE))) == NULL) {
// something broke, bail out
exit(1);
}
But this has the side effect of clobbering the "zones" pointer if realloc
fails, making anything other than a bail-out impossible (because the zone
table has been mangled). What I was thinking of doing was something like this:
if ((ztemp = realloc(zones, (zonecount + 2) * sizeof(ZONE))) == NULL) {
// something broke, tell the caller and let them deal with it
return ERROR_MEMALLOC;
} else {
// it worked, update the pointer
zones = ztemp;
}
What I was wondering was how realloc() actually behaved. Can the old value
of "zones" be considered to be valid if realloc() fails (i.e. returns NULL)?
In other words, can I continue on using the old value of "zones" (i.e. before
the reassignment) if realloc() fails, and just post an error to syslog along
the lines of "couldn't add zone table entry, out of memory"?
That said, "out of memory" is a pretty rare condition these days, what with
virtual memory and such, but I'd like to handle this situation as gracefully
as possible. If that means bailing out then fine, but if I can make my code
recover from the error, then I'd like to add the code to make that happen.
I've checked the Linux manpages on this, and K&R, but haven't found a
conclusive answer.
Thanks.
I'm currently playing around with a little spam filter for my Linksys NSLU2
(I would have used Spamassassin but that's slow even on my 2GHz Athlon64 - on
a 266MHz XScale it's likely to be intolerably slow). As part of that, I'm
keeping track of the DNSBL blocklists that are being queried using a
dynamically-allocated array.
When a new DNSBL zone is added to the zone array, I use realloc() to
increase the amount of memory available for the array. The newly-allocated
block then gets filled in with the zone's details, and a null block (one where
the "zone" pointer is set to NULL) is stored to act as a terminator.
At the moment, I'm using code like this:
if ((zones = realloc(zones, (zonecount + 2) * sizeof(ZONE))) == NULL) {
// something broke, bail out
exit(1);
}
But this has the side effect of clobbering the "zones" pointer if realloc
fails, making anything other than a bail-out impossible (because the zone
table has been mangled). What I was thinking of doing was something like this:
if ((ztemp = realloc(zones, (zonecount + 2) * sizeof(ZONE))) == NULL) {
// something broke, tell the caller and let them deal with it
return ERROR_MEMALLOC;
} else {
// it worked, update the pointer
zones = ztemp;
}
What I was wondering was how realloc() actually behaved. Can the old value
of "zones" be considered to be valid if realloc() fails (i.e. returns NULL)?
In other words, can I continue on using the old value of "zones" (i.e. before
the reassignment) if realloc() fails, and just post an error to syslog along
the lines of "couldn't add zone table entry, out of memory"?
That said, "out of memory" is a pretty rare condition these days, what with
virtual memory and such, but I'd like to handle this situation as gracefully
as possible. If that means bailing out then fine, but if I can make my code
recover from the error, then I'd like to add the code to make that happen.
I've checked the Linux manpages on this, and K&R, but haven't found a
conclusive answer.
Thanks.