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.
--
Phil. | Kitsune: Acorn RiscPC SA202 64M+6G ViewFinder ph*****@despammed.com (valid!)| Cheetah: Athlon64 3200+ A8VDeluxeV2 512M+100G http://www.philpem.me.uk/ | Tiger: Toshiba SatPro4600 Celeron700 256M+40G
No software patents! <http://www.eff.org/> / <http://www.ffii.org/> 10 3632
On Thu, 20 Apr 2006 19:13:41 +0100, Philip Pemberton
<ph*****@despammed.com> wrote: 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)?
From the standard:
"If memory for the new
object cannot be allocated, the old object is not deallocated and its
value is unchanged."
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.
--
Al Balmer
Sun City, AZ
According to the malloc functions manual, one can find (on the
RETURN VALUE section) the final phrase on the last paragraph: If
realloc() fails the original block is left untouched - it is not freed
or moved. So, if (zonecount + 2) > 0 is _always_ TRUE, your memory
block still there.
You can try to use a custom realloc() implementation, that wraps
errors and prints out some debugging info, and even use it as a macro
(i.e. for less function call overhead):
#include <stdlib.h>
#include <stdio.h>
/* __FILE__ and __LINE__ are usefull prepocessor macros */
#define XREALLOC(ptr, size) xrealloc(ptr, size, __FILE__, __LINE__)
void *
xrealloc (void *ptr, size_t size, char *fname, int lnum)
{
register void *value = realloc (ptr, size);
if (value == NULL)
{
fprintf (stderr, "%s:%d - realloc error\n", fname, lnum);
return NULL; //here the caller can deal with the error, but it's
recommended to exit ()
/* exit (EXIT_FAILURE); */
}
return value;
}
You can use the macro this way:
ztemp = (ZONE *) XREALLOC (zones, (zonecount + 2) * sizeof (ZONE));
and wrap (ztemp == NULL) to free memory and try again, et cetera.
If your application is linear (i.e. make the job in a serial way),
thre's no sense to wait some memory to apear, and exit() is the better
choice, but if we are expecting some memory to be realeased on the next
instants (wonder a multi-threaded application allocating/freeing memory
asychronously), make a try counter, sleep for a while, and try until
the counter reaches a limit (i.e. wait 100 us, and try 5 counts before
exit ()).
----mauricio
Al Balmer wrote: From the standard: "If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged."
Thanks for that - guess I'll have to try and get a copy of the C standard at
some point. K&R is great for most things, but I'm surprised it doesn't cover
realloc (or if it does it's certainly not listed in the index).
I gather that by "the standard" you mean "ISO/IEC 9899:1999: Programming
Language C"?
Thanks.
--
Phil. | Kitsune: Acorn RiscPC SA202 64M+6G ViewFinder ph*****@despammed.com (valid!)| Cheetah: Athlon64 3200+ A8VDeluxeV2 512M+100G http://www.philpem.me.uk/ | Tiger: Toshiba SatPro4600 Celeron700 256M+40G
No software patents! <http://www.eff.org/> / <http://www.ffii.org/>
Philip Pemberton wrote:
.... snip ... 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 is the correct way to handle it. On failure realloc will not
disturb the old pointer or the material to which it points.
--
I hear the voices. G W Bush, 2006-04-18
Philip Pemberton <ph*****@despammed.com> writes: Al Balmer wrote: From the standard: "If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged."
Thanks for that - guess I'll have to try and get a copy of the C standard at some point. K&R is great for most things, but I'm surprised it doesn't cover realloc (or if it does it's certainly not listed in the index).
I gather that by "the standard" you mean "ISO/IEC 9899:1999: Programming Language C"?
That's the current official standard, yes. Most implementations don't
yet fully support it; the older 1990 standard is almost universally
supported (often with extensions).
A draft of the standard, including the C99 standard with later
modifications ("Technical Corrigenda") merged in and marked with
change bars, is freely available as n1124.pdf. I have a copy of the
actual standard (for which I paid $18 to ANSI), but these days I
almost always use n1124 instead.
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Philip Pemberton wrote: Al Balmer wrote: From the standard: "If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged." Thanks for that - guess I'll have to try and get a copy of the C standard at some point. K&R is great for most things, but I'm surprised it doesn't cover realloc (or if it does it's certainly not listed in the index).
<fx: wanders off to grab copy of K&R2>
It's in the index of the second edition. If you have the first edition
then I suggest you go out and buy the "modern" version that was
published in 1989 since it tells you about all sorts of cool "new"
things, such as function prototypes and void.
I gather that by "the standard" you mean "ISO/IEC 9899:1999: Programming Language C"?
I'm sure he does. I suggest you look here http://clc-wiki.net/wiki/c_standard
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro: http://clc-wiki.net/wiki/Intro_to_clc
Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
On Thu, 20 Apr 2006 20:30:46 +0100, Philip Pemberton
<ph*****@despammed.com> wrote: Al Balmer wrote: From the standard: "If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged." Thanks for that - guess I'll have to try and get a copy of the C standard at some point. K&R is great for most things, but I'm surprised it doesn't cover realloc (or if it does it's certainly not listed in the index).
It's listed in the second edition - page 252. A short paragraph, in
the usual K&R style of no unnecessary words :-) I gather that by "the standard" you mean "ISO/IEC 9899:1999: Programming Language C"?
Yes. It's available as a PDF from ANSI for $18.00. That's what I use.
--
Al Balmer
Sun City, AZ
"pragma" <mp****@if.ufrgs.br> wrote in message
news:11*********************@v46g2000cwv.googlegro ups.com... According to the malloc functions manual, one can find (on the RETURN VALUE section) the final phrase on the last paragraph: If realloc() fails the original block is left untouched - it is not freed or moved. So, if (zonecount + 2) > 0 is _always_ TRUE, your memory block still there.
You can try to use a custom realloc() implementation, that wraps errors and prints out some debugging info, and even use it as a macro (i.e. for less function call overhead):
#include <stdlib.h> #include <stdio.h>
/* __FILE__ and __LINE__ are usefull prepocessor macros */ #define XREALLOC(ptr, size) xrealloc(ptr, size, __FILE__, __LINE__)
void * xrealloc (void *ptr, size_t size, char *fname, int lnum) { register void *value = realloc (ptr, size);
if (value == NULL) { fprintf (stderr, "%s:%d - realloc error\n", fname, lnum); return NULL; //here the caller can deal with the error, but it's recommended to exit () /* exit (EXIT_FAILURE); */ } return value; }
You can use the macro this way:
ztemp = (ZONE *) XREALLOC (zones, (zonecount + 2) * sizeof (ZONE));
And why would you need to cast XREALLOC() here?
and wrap (ztemp == NULL) to free memory and try again, et cetera.
On Thu, 20 Apr 2006 20:30:46 +0100, Philip Pemberton
<ph*****@despammed.com> wrote: Al Balmer wrote: From the standard: "If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged."
Thanks for that - guess I'll have to try and get a copy of the C standard at some point. K&R is great for most things, but I'm surprised it doesn't cover realloc (or if it does it's certainly not listed in the index).
It's in the index on page 269 in my copy. The index refers to page
252. The wording is a tad different but it matches the intent that Al
quoted.
Remove del for email
Philip Pemberton wrote:
<snip> That said, "out of memory" is a pretty rare condition these days, what with virtual memory and such,
This is OT, but virtual memory is neither inexhaustible nor necessarily
unbounded. My machine in particular has a fixed amount of virtual memory,
and it does get exhausted (mostly by rude applications who *could* do with
less memory if they hadn't been written with the assumption that large
amounts of memory will magically appear and disappear). I still prefer
applications crashing left and right to losing my system through thrashing.
but I'd like to handle this situation as gracefully as possible.
Good for you. Usually a best effort suffices. Whatever you do is better than
assuming it never fails, even if it's just displaying "out of memory" rather
than "segmentation fault".
S. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Roy |
last post by:
Hi all :
My code below :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *cat(char *s, const char *t)
{
char *tmp;
|
by: Walter Roberson |
last post by:
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?
The C89 standard has some reference to undefined behaviour if one
realloc()'s memory...
|
by: Martin Joergensen |
last post by:
Hi,
I wanted to try something which I think is a very good
exercise... I read in data from the keyboard and store them in a
structure. There's a pointer called "data_pointer" which I use to...
|
by: ivan.leben |
last post by:
Let's say I have a piece of allocated memory which I want to expand and
reuse if possible or allocate in a different part of RAM if resizing is
not possible, however, in the latter case I don't...
|
by: Robert Seacord |
last post by:
The C standard doesn't say anything about what happens when you call
realloc with a size argument of 0. Both glibc and openbsd appear to
return a valid pointer to a zero-sized object.. e.g. the...
|
by: banansol |
last post by:
Hi,
I just want to get this right.
A call to realloc() will return NULL on error and the original memory
is left untouched,
both when requesting a larger or a smaller size that the original,...
|
by: Kenneth Brody |
last post by:
I looked at my copy of n1124, and I didn't see anything about this
particular situation...
What happens if you realloc() to a size of zero?
Implementations are allowed to return NULL on...
|
by: Igal |
last post by:
hay, i'm doing this program. having problem wiht realloc in the
function that reads data structures into array (pointer - bp2), this
happens after reading the second record. when call to realloc....
|
by: Bill Cunningham |
last post by:
My string.h headers declares two functions I have been using called
memfrob and strfry. They are encryption types functions. My man pages say
they are standard to linux c and gnu c. They sure...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |