Discussion:
style question,itoa
(too old to reply)
Syren Baran
2008-01-22 21:51:43 UTC
Permalink
Hi,
i wrote this helper function. But somehow i cant help the feeling its a
bit kludgy. Any suggestions for improvement (aside from the fact it
doesnt handle max-negative-value correctly)?
--snip-
char* itoa(int src){
char* retval=(char*)malloc(20*sizeof(char));
char* tmp=(char*)malloc(19*sizeof(char));
int pos=0,pos2=0;
if (src<0){
pos=1;
*retval='-';
src=-src;
}
while(src>0){
*(tmp+pos2)=(char)('0'+(src%10));
pos2++;
src/=10;
}
pos2--;
while(pos2>=0){
*(retval+pos)=*(tmp+pos2);
pos++;
pos2--;
}
*(retval+pos)=0;
free(tmp);
return retval;
}
--snap-
David Schwartz
2008-01-22 23:30:10 UTC
Permalink
Post by Syren Baran
i wrote this helper function. But somehow i cant help the feeling its a
bit kludgy. Any suggestions for improvement (aside from the fact it
doesnt handle max-negative-value correctly)?
--snip-
char* itoa(int src){
char* retval=(char*)malloc(20*sizeof(char));
char* tmp=(char*)malloc(19*sizeof(char));
No point in using 'malloc' for 'tmp' since it's fixed size and small.
20 bytes on the stack will save a 'malloc' and a 'free' call for each
invocation.
Post by Syren Baran
int pos=0,pos2=0;
if (src<0){
pos=1;
*retval='-';
src=-src;
}
while(src>0){
*(tmp+pos2)=(char)('0'+(src%10));
pos2++;
src/=10;
}
pos2--;
while(pos2>=0){
*(retval+pos)=*(tmp+pos2);
pos++;
pos2--;
}
*(retval+pos)=0;
It's more efficient to do more than one digit at a time, but that's
basically how you have to do it.
Post by Syren Baran
free(tmp);
return retval;}
The caller has to 'free' 'retval' when it's done. It might be more
sensible to have the caller pass in a buffer. This will allow the
caller to use a buffer on its stack if that makes the most sense for
it.

DS
Syren Baran
2008-01-23 00:51:51 UTC
Permalink
Post by David Schwartz
Post by Syren Baran
i wrote this helper function. But somehow i cant help the feeling its a
bit kludgy. Any suggestions for improvement (aside from the fact it
doesnt handle max-negative-value correctly)?
--snip-
char* itoa(int src){
char* retval=(char*)malloc(20*sizeof(char));
char* tmp=(char*)malloc(19*sizeof(char));
No point in using 'malloc' for 'tmp' since it's fixed size and small.
20 bytes on the stack will save a 'malloc' and a 'free' call for each
invocation.
Yepp, definatly right.
Post by David Schwartz
Post by Syren Baran
int pos=0,pos2=0;
if (src<0){
pos=1;
*retval='-';
src=-src;
}
while(src>0){
*(tmp+pos2)=(char)('0'+(src%10));
pos2++;
src/=10;
}
pos2--;
while(pos2>=0){
*(retval+pos)=*(tmp+pos2);
pos++;
pos2--;
}
*(retval+pos)=0;
It's more efficient to do more than one digit at a time, but that's
basically how you have to do it.
Yes. Buts thats not really what buggering me.
I have a strange feeling i should be able to this with with only one
buffer. If my memory serves me correctly theres something like an
"exchange" asm command (on x86). Maybe the compiler actually optimizes e
the output or i can give it a some hints. I guess i´ll have a look.
Post by David Schwartz
Post by Syren Baran
free(tmp);
return retval;}
The caller has to 'free' 'retval' when it's done.
Its intended that way.
Post by David Schwartz
It might be more
sensible to have the caller pass in a buffer. This will allow the
caller to use a buffer on its stack if that makes the most sense for
it.
Dont intend to change that. I´m comfortable with that.
Post by David Schwartz
DS
Alex Colvin
2008-01-23 01:28:40 UTC
Permalink
try using a recursive conversion
convert the n/10
append n%19
--
mac the naïf
Syren Baran
2008-01-23 02:25:39 UTC
Permalink
Post by Alex Colvin
try using a recursive conversion
convert the n/10
append n%19
I *think* i know what youre trying to suggest (if 19 above is supposed
to be a 10).
However that involves two pointers (&pos and retval) to be copied to the
stack and a jmp to be called for every recursive function call. Too much
execution speed sacrificed to save the tmp var.
Ok, i wasnt expecting anything near quakes fast inverse sqrt trick but i
think i?ll try to find a other solution.
Scott Lurndal
2008-01-23 02:44:03 UTC
Permalink
Post by Syren Baran
Post by Alex Colvin
try using a recursive conversion
convert the n/10
append n%19
I *think* i know what youre trying to suggest (if 19 above is supposed
to be a 10).
However that involves two pointers (&pos and retval) to be copied to the
stack and a jmp to be called for every recursive function call. Too much
execution speed sacrificed to save the tmp var.
Ok, i wasnt expecting anything near quakes fast inverse sqrt trick but i
think i?ll try to find a other solution.
/**
* itoa
*
* Format an integer value as a string in a specified base.
*
* @param value The value to format
* @param base The base (2-16) in which to format
* @param buffer The buffer to format into
* @param bufsize The number of available bytes in buffer
* @param fieldwidth The width of the field.
* @param sign 0: Treat value as unsigned 1: Treat value as signed
* @returns A pointer to start of the supplied buffer.
*/
char *
itoa(uint64 value,
int32 base,
char *buffer,
size_t bufsize,
size_t fieldwidth,
int32 sign)
{
char *cp = &buffer[bufsize-1];
int neg = 0;
int pad = (fieldwidth != 0);

if (fieldwidth == 0) {
fieldwidth = bufsize;
}

*cp = '\0';

if (sign && ((int32)value < 0)) {
neg++;
value = (uint32)(-(int32)value);
}

do {
*--cp = "0123456789abcdef"[value%base];
value /= base;
} while ((value) && (--fieldwidth > 0));

if (pad) {
while (--fieldwidth > 0) {
*--cp = '0';
}
}

if (neg) {
*--cp = '-';
}

return cp;
}
Syren Baran
2008-01-23 03:34:01 UTC
Permalink
Post by Syren Baran
/**
* itoa
Neat. Real neat.
I think i'll also fill the buffer from the back and memmove afterwards.
Post by Syren Baran
*--cp = "0123456789abcdef"[value%base];
This line is damn nice! I'll remember that trick. Thanks.
Scott Lurndal
2008-01-23 19:16:53 UTC
Permalink
Post by Syren Baran
Post by Syren Baran
/**
* itoa
Neat. Real neat.
I think i'll also fill the buffer from the back and memmove afterwards.
Post by Syren Baran
*--cp = "0123456789abcdef"[value%base];
This line is damn nice! I'll remember that trick. Thanks.
There's a bug in the original. The cast to int32 in the sign check
should be cast to int64, unless it is a big-endian machine.

scott
Ben Bacarisse
2008-01-23 21:22:34 UTC
Permalink
Post by Scott Lurndal
Post by Syren Baran
Post by Syren Baran
/**
* itoa
Neat. Real neat.
I think i'll also fill the buffer from the back and memmove afterwards.
Post by Syren Baran
*--cp = "0123456789abcdef"[value%base];
This line is damn nice! I'll remember that trick. Thanks.
There's a bug in the original. The cast to int32 in the sign check
should be cast to int64, unless it is a big-endian machine.
I don't see how the endian-ness can come into it. C's conversions are
based on value, not representation. The conversion from uint64 to
either int32 or int64 is a potential portability problem -- the value
may not be representable and this can raise signal or other
implementation defined behaviour.
--
Ben.
Ben Bacarisse
2008-01-23 12:22:51 UTC
Permalink
I think you need to fix a few boundary conditions in this code.
Post by Syren Baran
/**
* itoa
*
* Format an integer value as a string in a specified base.
*
*/
char *
itoa(uint64 value,
int32 base,
char *buffer,
size_t bufsize,
size_t fieldwidth,
int32 sign)
{
char *cp = &buffer[bufsize-1];
int neg = 0;
int pad = (fieldwidth != 0);
if (fieldwidth == 0) {
fieldwidth = bufsize;
I think this should be bufsize - 1.
Post by Syren Baran
}
*cp = '\0';
if (sign && ((int32)value < 0)) {
neg++;
value = (uint32)(-(int32)value);
I think you need to decrement fieldwidth here.
Post by Syren Baran
}
do {
*--cp = "0123456789abcdef"[value%base];
value /= base;
} while ((value) && (--fieldwidth > 0));
if (pad) {
while (--fieldwidth > 0) {
The previous loop can terminate with fieldwidth == 0 so this one will
not stop soon!
Post by Syren Baran
*--cp = '0';
}
}
if (neg) {
*--cp = '-';
This can underflow the buffer if the field is already full.
Post by Syren Baran
}
return cp;
}
The behaviour of leaving an initial segment of the buffer unwritten is
little odd and should at least be documented. Personally, if you are
always going to write from the end, I'd always fill the buffer but
with spaces rather than '0' (if pad was not set).
--
Ben.
Scott Lurndal
2008-01-23 19:39:06 UTC
Permalink
Post by Ben Bacarisse
I think you need to fix a few boundary conditions in this code.
Thanks for the review, it was a quick & dirty.
Post by Ben Bacarisse
The behaviour of leaving an initial segment of the buffer unwritten is
little odd and should at least be documented. Personally, if you are
always going to write from the end, I'd always fill the buffer but
with spaces rather than '0' (if pad was not set).
If the caller uses the return value rather than the buffer
itself, things work correctly, so long as the caller isn't trying
to format in place. Either spaces or nul's would probably
work, 6 of one, half dozen of the other. I'd tend to favor the nul
as a zero-length string will be more noticable than a slightly wider
string.

scott
Frank Cusack
2008-01-23 23:22:22 UTC
Permalink
char *itoa(uint64 value, ...)
awesome job Scott. just the function is now misnamed, since you convert
a uint64 not an int. ulltoa()?

-frank
Logan Shaw
2008-01-23 03:28:56 UTC
Permalink
Post by Syren Baran
Yes. Buts thats not really what buggering me.
I have a strange feeling i should be able to this with with only one
buffer.
There's absolutely no reason you can't take the same approach you
had been using except simply reverse in place in a single buffer:

char* itoa(int i) {
char* buffer = malloc(20); /* assumes big enough */
char* writepos = buffer;
char* revstart;
char* revend;
char temp;

if (i < 0) {
*writepos++ = '-';
i = -i;
}

revstart = writepos;

do {
*writepos++ = ((char) (i % 10)) + '0';
i /= 10;
} while (i != 0);

revend = writepos - 1;

*writepos++ = 0;

/* now reverse */
while (revstart < revend) {
temp = *revstart;
*revstart = *revend;
*revend = temp;
revstart++;
revend--;
}

return buffer;
}

This version, like your original one, doesn't take into account
that perhaps negating a number won't always yield a positive
number.

- Logan
Robert Latest
2008-01-23 08:38:53 UTC
Permalink
Post by Syren Baran
Post by David Schwartz
The caller has to 'free' 'retval' when it's done.
Its intended that way.
Post by David Schwartz
It might be more
sensible to have the caller pass in a buffer. This will allow the
caller to use a buffer on its stack if that makes the most sense for
it.
Dont intend to change that. I´m comfortable with that.
That's puzzling. But you still need to add code that checks for malloc()s
retun value.

robert
Syren Baran
2008-01-23 18:42:20 UTC
Permalink
Post by Robert Latest
Post by Syren Baran
Post by David Schwartz
The caller has to 'free' 'retval' when it's done.
Its intended that way.
Post by David Schwartz
It might be more
sensible to have the caller pass in a buffer. This will allow the
caller to use a buffer on its stack if that makes the most sense for
it.
Dont intend to change that. I´m comfortable with that.
That's puzzling.
Not really. I dont like using arrays on the stack unless i can know for
certain they cant overflow. But thats my personal style.
Post by Robert Latest
But you still need to add code that checks for malloc()s
retun value.
Theoreticly, yes.
Since the program i´ll use it cant eat up memory at an alarming rate i
prefer manual intervention (being able to tell the program not to
accecpt further connections and deny further functions calls that can
allocate memory).
Aside from that even a nun-NULL return value from malloc does not
garantee that memory is available on Linux (see man 3 malloc).
Post by Robert Latest
robert
Frank Cusack
2008-01-23 19:54:27 UTC
Permalink
Post by Syren Baran
Post by Robert Latest
Post by Syren Baran
Post by David Schwartz
The caller has to 'free' 'retval' when it's done.
Its intended that way.
Post by David Schwartz
It might be more
sensible to have the caller pass in a buffer. This will allow the
caller to use a buffer on its stack if that makes the most sense for
it.
Dont intend to change that. I´m comfortable with that.
That's puzzling.
Not really. I dont like using arrays on the stack unless i can know
for certain they cant overflow. But thats my personal style.
Yes but in this case you do know they can't overflow. An int is at
most 11 chars.

Having the caller pass in a buffer also doesn't REQUIRE that that buffer
be on the stack. But I assume you are optimizing for speed (?) since
you aren't simply using sprintf(). In which case you probably would do
better to use the stack.

Lastly, when the caller has to free() something, it's nicer if the
caller actually has to malloc() it as well. It helps you read the
code better.

-frank
Syren Baran
2008-01-24 02:53:51 UTC
Permalink
Post by Frank Cusack
Post by Syren Baran
Post by Syren Baran
Dont intend to change that. I´m comfortable with that.
That's puzzling.
Not really. I dont like using arrays on the stack unless i can know
for certain they cant overflow. But thats my personal style.
Yes but in this case you do know they can't overflow. An int is at
most 11 chars.
Since i dont know if int can be 64bit i decided to play save there.
(18bytes suffice for the number +1 for sign and +1 for the null
termination).
But your statement is irrelevant anyway. If i have a pointer to stack
space array (or offset into an array) i have to perform additional range
checks.
Post by Frank Cusack
Having the caller pass in a buffer also doesn't REQUIRE that that buffer
be on the stack. But I assume you are optimizing for speed (?) since
you aren't simply using sprintf(). In which case you probably would do
better to use the stack.
Yes, i do optimize for speed, as much as possible, without sacrificing
robustness. And as i said i prefer pointers to arrays. Ok, so
malloc/free add a larger overhead than range checks, but the worst case
scenarios for heap corruption arent nearly as bad as for stack corruption.
Post by Frank Cusack
Lastly, when the caller has to free() something, it's nicer if the
caller actually has to malloc() it as well.
Call me lazy if you wish, i prefer writing a line less ;)
Post by Frank Cusack
It helps you read the
code better.
Good to know you know that i will have an easier time reading my code
when using functions i wrote that behave as i wanted to. I didnt know
that yet.
Post by Frank Cusack
-frank
Frank Cusack
2008-01-24 19:29:58 UTC
Permalink
Post by Syren Baran
Post by Frank Cusack
Lastly, when the caller has to free() something, it's nicer if the
caller actually has to malloc() it as well.
Call me lazy if you wish, i prefer writing a line less ;)
Post by Frank Cusack
It helps you read the
code better.
Good to know you know that i will have an easier time reading my code
when using functions i wrote that behave as i wanted to. I didnt know
that yet.
an all too common error to assume

a) no one else will ever read your code.
b) you will remember how any function behaves.

admittedly in this case it's rather trivial.

-frank
Syren Baran
2008-01-24 20:02:12 UTC
Permalink
Post by Frank Cusack
Post by Syren Baran
Good to know you know that i will have an easier time reading my code
when using functions i wrote that behave as i wanted to. I didnt know
that yet.
an all too common error to assume
a) no one else will ever read your code.
b) you will remember how any function behaves.
I learned b) the hard way a long time ago. Thats why i document the
functions. That way they will not only "behave as i wanted to", but also
as i document them.
Post by Frank Cusack
admittedly in this case it's rather trivial.
Yupp, but anyway that file will contain the notice "All functions below
that return a char* require the caller to free the char*."
Post by Frank Cusack
-frank
moi
2008-01-24 23:20:49 UTC
Permalink
Post by Syren Baran
Post by Frank Cusack
Post by Syren Baran
Good to know you know that i will have an easier time reading my code
when using functions i wrote that behave as i wanted to. I didnt know
that yet.
an all too common error to assume
a) no one else will ever read your code. b) you will remember how any
function behaves.
I learned b) the hard way a long time ago. Thats why i document the
functions. That way they will not only "behave as i wanted to", but also
as i document them.
Post by Frank Cusack
admittedly in this case it's rather trivial.
Yupp, but anyway that file will contain the notice "All functions below
that return a char* require the caller to free the char*."
Post by Frank Cusack
-frank
For this kind of formatting-functions the snprintf() kind of interface is
perfect:
*) it cannot overrun the buffer (once coded correctly)
*) if it would: it returns a negative value.
*) if it succeeds, it returns the amount written,
such that buffer[return_value] == '\0'; which makes is easy to fill the
buffer in multiple calls, and without excess copying.

Utility functions, returning malloc()ed chunks need return value testing
by the caller. The snprintf() method does so also, but (on failure) it
does *not* need to free() the preceding chunks, which means it is shorten
and less error prone.

YMMV,
AvK
Frank Cusack
2008-01-25 01:21:09 UTC
Permalink
Post by moi
For this kind of formatting-functions the snprintf() kind of interface is
*) it cannot overrun the buffer (once coded correctly)
*) if it would: it returns a negative value.
No.

snprintf() "always" returns the number of bytes that it *would* have
written, minus 1, regardless of whether or not there was room. That
lets you do 2 things.

1. you will know the extra amount of buffer space needed if you are short
2. you can do 'snprintf(NULL, 0, fmt, ...)' to find out the amount of
space needed.

However, the definition of snprintf() has changed over time and unless
you know your code will only be used on SUSv3 conforming systems, you
cannot depend on this behavior. It's better to use slprintf().

-frank
moi
2008-01-26 12:49:35 UTC
Permalink
Post by Frank Cusack
Post by moi
For this kind of formatting-functions the snprintf() kind of interface
it returns a negative value.
No.
snprintf() "always" returns the number of bytes that it *would* have
written, minus 1, regardless of whether or not there was room. That
lets you do 2 things.
Oops, I stand corrected.
Post by Frank Cusack
1. you will know the extra amount of buffer space needed if you are
short 2. you can do 'snprintf(NULL, 0, fmt, ...)' to find out the amount
of
space needed.
However, the definition of snprintf() has changed over time and unless
you know your code will only be used on SUSv3 conforming systems, you
cannot depend on this behavior. It's better to use slprintf().
Maybe I have been confused by one of the older definitions.

Anyway, what I *intended* to say was, that when designing an interface
for a 'formatting' function, you'll have to choose how to represent (and
handle) 'can not be done' and 'does not fit' cases.
IMHO an interface that uses a -1 return (but >= buffsize would also do)
will be reasonably easy for the caller:

char buff[SOMESIZE];
size_t pos;
int rec;

pos = 0;
rc = mysnprintf(buff, sizeof buff, fmt, args);
if (rc < 0) goto disaster;
pos += rc;

rc = mysnprintf(buff+pos, sizeof buff - pos, fmt2, moreargs);
if (rc < 0) goto disaster;
pos += rc;

.. etc ...

In the case of snprintf(), the "if (rc < 0)" condition should of course
also include (rc+pos >= sizeof buff).

AvK
Frank Cusack
2008-01-25 01:22:27 UTC
Permalink
Post by moi
*) if it succeeds, it returns the amount written,
such that buffer[return_value] == '\0';
you also cannot depend on this unless you are certain of the
implementation.

-frank
Syren Baran
2008-01-25 01:50:40 UTC
Permalink
Post by moi
Post by Syren Baran
Post by Frank Cusack
Post by Syren Baran
Good to know you know that i will have an easier time reading my code
when using functions i wrote that behave as i wanted to. I didnt know
that yet.
an all too common error to assume
a) no one else will ever read your code. b) you will remember how any
function behaves.
I learned b) the hard way a long time ago. Thats why i document the
functions. That way they will not only "behave as i wanted to", but also
as i document them.
Post by Frank Cusack
admittedly in this case it's rather trivial.
Yupp, but anyway that file will contain the notice "All functions below
that return a char* require the caller to free the char*."
Post by Frank Cusack
-frank
For this kind of formatting-functions the snprintf() kind of interface is
*) it cannot overrun the buffer (once coded correctly)
*) if it would: it returns a negative value.
*) if it succeeds, it returns the amount written,
vs.
*) it cannot overrun the buffer (it malloc's a sufficient buffer)
*) it wont fail if the memory can be alloc'd. [1]
*) it succeeds and returns the char*
Post by moi
such that buffer[return_value] == '\0'; which makes is easy to fill the
buffer in multiple calls, and without excess copying.
Utility functions, returning malloc()ed chunks need return value testing
by the caller.
Oehm, why?
Post by moi
The snprintf() method does so also, but (on failure) it
does *not* need to free() the preceding chunks, which means it is shorten
and less error prone.
Ok, but what do i do if i check the error condition and figure out i
need a larger buffer anyway? Allocate a new buffer? In that case i can
just as well have the utility function allocate the buffer for me, right?
Post by moi
YMMV,
AvK
[1] Checking every small malloc is the logical inverse of calling the
lottery service every day asking if i have won even though i didnt get a
ticket. Sure somebody may have accidently written my name on the ticket
and won, but its not likely.
Frank Cusack
2008-01-25 03:12:09 UTC
Permalink
Post by Syren Baran
[1] Checking every small malloc is the logical inverse of calling the
lottery service every day asking if i have won even though i didnt get
a ticket. Sure somebody may have accidently written my name on the
ticket and won, but its not likely.
logical inverse is right. while it doesn't make sense to check the
lottery numbers if you didn't buy a ticket, it does make sense to
check the return value from all library calls if you are going to use
the result.

of course if you are just going to exit anyway, you may as well deref
the NULL pointer[1]. but if you can handle the error gracefully then it
doesn't matter what the call is, check the error.

-frank
[1] except where you want to provide a failure reason other than the
ominous SEGV.
Logan Shaw
2008-01-24 03:26:34 UTC
Permalink
Post by Frank Cusack
Post by Syren Baran
Not really. I dont like using arrays on the stack unless i can know
for certain they cant overflow. But thats my personal style.
Yes but in this case you do know they can't overflow. An int is at
most 11 chars.
I think you're implying that machines don't exist where "int" is
64-bit. :-)

- Logan
Frank Cusack
2008-01-24 19:34:05 UTC
Permalink
Post by Logan Shaw
Post by Frank Cusack
Post by Syren Baran
Not really. I dont like using arrays on the stack unless i can know
for certain they cant overflow. But thats my personal style.
Yes but in this case you do know they can't overflow. An int is at
most 11 chars.
I think you're implying that machines don't exist where "int" is
64-bit. :-)
what ILP64 systems exist?
Frank Cusack
2008-01-25 03:16:06 UTC
Permalink
Post by Frank Cusack
Post by Logan Shaw
I think you're implying that machines don't exist where "int" is
64-bit. :-)
what ILP64 systems exist?
apparently, Cray T3E and some others.
Logan Shaw
2008-01-25 04:17:10 UTC
Permalink
Post by Frank Cusack
Post by Logan Shaw
Post by Frank Cusack
Post by Syren Baran
Not really. I dont like using arrays on the stack unless i can know
for certain they cant overflow. But thats my personal style.
Yes but in this case you do know they can't overflow. An int is at
most 11 chars.
I think you're implying that machines don't exist where "int" is
64-bit. :-)
what ILP64 systems exist?
Good question. Until you named one Cray machine and I found that
old versions of gcc supported ILP64 when targeting MIPS (though
turned off by default), I did not actually know that they did
exist.

I was merely trying to say that it's an assumption, and those are
the kind of things that will come back and bite you one day.
Perhaps somebody will compile your code for some future system
where ILP64 is used. Perhaps a future embedded processor will
implement only 64-bit integer operations because it simplifies
the design of the chip or something.

Probably not a problem on a practical level, though.

- Logan
Spoon
2008-01-24 13:14:43 UTC
Permalink
Post by Syren Baran
Aside from that even a nun-NULL return value from malloc does not
guarantee that memory is available on Linux (see man 3 malloc).
Memory overcommit can be disabled.
Syren Baran
2008-01-24 15:21:19 UTC
Permalink
Post by Spoon
Post by Syren Baran
Aside from that even a nun-NULL return value from malloc does not
guarantee that memory is available on Linux (see man 3 malloc).
Memory overcommit can be disabled.
Which requires root priviliges.
Rainer Weikusat
2008-01-24 14:06:15 UTC
Permalink
Post by Syren Baran
Post by Robert Latest
Post by Syren Baran
Post by David Schwartz
The caller has to 'free' 'retval' when it's done.
Its intended that way.
Post by David Schwartz
It might be more
sensible to have the caller pass in a buffer. This will allow the
caller to use a buffer on its stack if that makes the most sense for
it.
Dont intend to change that. I´m comfortable with that.
That's puzzling.
Not really. I dont like using arrays on the stack unless
i can know for certain they cant overflow. But thats my personal
style.
In this case, the conversion code wouldn't be using a stack allocated
value but the code calling it. Coincendetally, that would be the code
'knowing' what storage management requirements have to be met while
the called code (of a 'library-type' subroutine) cannot.

It is decidedly not 'your personal style' to write code with lots of
technically useless malloc and free calls, this is common for
'OOP'-programmers not usually working in memory-limited environment or
on performance, safety or security criticial code. The only real
accomplishments by doing so are slowing the code down without a gain,
inserting additional points of 'random'[*] failures and enabling
certain types of (malloc-implementation-based) exploits.

[*] Supposed to mean 'failing because of not easily
observable, dynamically changing external circumstances'.
Post by Syren Baran
Post by Robert Latest
But you still need to add code that checks for malloc()s retun value.
Theoreticly, yes.
.
No, practically, yes. malloc can and does fail and invocation of a
library-type subroutine should certainly not lead to
program-termination-by-SIGSEV at random. Instead, the caller should
have the ablity to deal with the failure.
Post by Syren Baran
Since the program i´ll use it cant eat up memory at an alarming rate i
prefer manual intervention (being able to tell the program not to
accecpt further connections and deny further functions calls that can
allocate memory).
Since the OS used to run your program manages the available RAM, no
matter how hard you try to ignore that, there is no way to determine a
priori when memory allocations would fail.
Post by Syren Baran
Aside from that even a nun-NULL return value from malloc does not
garantee that memory is available on Linux (see man 3 malloc).
But a NULL return values 'guarantees' that memory is not available.
Syren Baran
2008-01-24 15:55:39 UTC
Permalink
Post by Rainer Weikusat
Post by Syren Baran
Not really. I dont like using arrays on the stack unless
i can know for certain they cant overflow. But thats my personal
style.
In this case, the conversion code wouldn't be using a stack allocated
value but the code calling it. Coincendetally, that would be the code
'knowing' what storage management requirements have to be met while
the called code (of a 'library-type' subroutine) cannot.
Dont pinpoint this down to this one function which has a fixed size
allocation. Other helper functions dont return a fixed size char*, thus
knowing the space available in an array is of no help.
Post by Rainer Weikusat
It is decidedly not 'your personal style' to write code with lots of
technically useless malloc and free calls,
Good to know someone decided for me which style i am to use ;)
Post by Rainer Weikusat
this is common for
'OOP'-programmers not usually working in memory-limited environment or
on performance,
How about OOP-programmers working in a memory limited environment with
limited performance? Want links to J2ME games i wrote?
safety or security criticial code. The only real
Post by Rainer Weikusat
accomplishments by doing so are slowing the code down without a gain,
inserting additional points of 'random'[*] failures and enabling
certain types of (malloc-implementation-based) exploits.
Care to elaborate about the later? I do like learning about potential
problems and how to avoid them.
Post by Rainer Weikusat
[*] Supposed to mean 'failing because of not easily
observable, dynamically changing external circumstances'.
Post by Syren Baran
Post by Robert Latest
But you still need to add code that checks for malloc()s retun value.
Theoreticly, yes.
.
No, practically, yes. malloc can and does fail and invocation of a
library-type subroutine should certainly not lead to
program-termination-by-SIGSEV at random. Instead, the caller should
have the ablity to deal with the failure.
ENOMEM is hardly a random failure. Long before that happens i would
expect the system to send a message like "running low on swap space".
Post by Rainer Weikusat
Post by Syren Baran
Since the program i´ll use it cant eat up memory at an alarming rate i
prefer manual intervention (being able to tell the program not to
accecpt further connections and deny further functions calls that can
allocate memory).
Since the OS used to run your program manages the available RAM, no
matter how hard you try to ignore that, there is no way to determine a
priori when memory allocations would fail.
Oehm? Running low on swap space isnt sign enough?
Post by Rainer Weikusat
Post by Syren Baran
Aside from that even a nun-NULL return value from malloc does not
garantee that memory is available on Linux (see man 3 malloc).
But a NULL return values 'guarantees' that memory is not available.
Ok, but what is your suggestion?
Wrap every malloc like
if (!malloc(..)){
fprintf(stderr,"Out of memory!\n");
exit(1);
}
?
Checking every single malloc in a bigger application for possible
solutions to ENOMEM's is hardly feasible.
Rainer Weikusat
2008-01-25 08:02:43 UTC
Permalink
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
Not really. I dont like using arrays on the stack unless
i can know for certain they cant overflow. But thats my personal
style.
In this case, the conversion code wouldn't be using a stack allocated
value but the code calling it. Coincendetally, that would be the code
'knowing' what storage management requirements have to be met while
the called code (of a 'library-type' subroutine) cannot.
Dont pinpoint this down to this one function which has a fixed size
allocation. Other helper functions dont return a fixed size char*,
thus knowing the space available in an array is of no help.
This doesn't address the issue I was writing about.
Post by Syren Baran
is decidedly not 'your personal style' to write code with lots of
Post by Rainer Weikusat
technically useless malloc and free calls,
Good to know someone decided for me which style i am to use ;)
That you call something 'your personal style' which is actually
commonplace in a lot of code just indicates that you haven't seen much
code.
Post by Syren Baran
Post by Rainer Weikusat
this is common for 'OOP'-programmers not usually working in
memory-limited environment or on performance,
How about OOP-programmers working in a memory limited environment
with limited performance? Want links to J2ME games i wrote?
Obviously, every computer can be regarded as memory-limited because it
has only a limited amount of memory. So, yes, you are alway working in
a memory-limited environment and should never assume that it is just
going to be there. There are just occasions when this assumption will
bite back harder and more often, eg if 'memory-limited' means (as I
intended it to be understood) 'failures caused by OOM conditions
actually happen frequently' and must (insofar possible) be restricted
to non-critical and (ideally) not user-visible components. Eg, a flash
write killed halfway through because of ressource shortage will result
in a unusable device, followed by an angry phonecall by some customer
and the need to provide a replacement unit.

Conventional theory in this respect would be that this doesn't really
matter if it is only a few customers and while I have to accept this
because it is economically sensible, I strongly object to the idea
that this is how it should be.
Post by Syren Baran
safety or security criticial code. The only real
Post by Rainer Weikusat
accomplishments by doing so are slowing the code down without a gain,
inserting additional points of 'random'[*] failures and enabling
certain types of (malloc-implementation-based) exploits.
Care to elaborate about the later? I do like learning about potential
problems and how to avoid them.
Try googling for malloc-based overrun exploits.
Post by Syren Baran
Post by Rainer Weikusat
[*] Supposed to mean 'failing because of not easily
observable, dynamically changing external circumstances'.
Post by Syren Baran
Post by Robert Latest
But you still need to add code that checks for malloc()s retun value.
Theoreticly, yes.
.
No, practically, yes. malloc can and does fail and invocation of a
library-type subroutine should certainly not lead to
program-termination-by-SIGSEV at random. Instead, the caller should
have the ablity to deal with the failure.
ENOMEM is hardly a random failure. Long before that happens i would
expect the system to send a message like "running low on swap
space".
It is hardly a random failure as long as there is exactly one program
running on some computer which allocates memory. But this is never
true for anything UNIX(*)-like, except insofar that 'every' programmer
only cares for one program at any given time, namely, the one he is
working on, and maintains a state of blissful ignorance wrt the
universe around it, aka "isn't there a system call to determine how
much memory is hic et nunc available to me [alone]"?

A possible implementation would be

unsigned sys_personal_reserve_storage(uid_t unused)
{
return 0;
}

[...]
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
Aside from that even a nun-NULL return value from malloc does not
garantee that memory is available on Linux (see man 3 malloc).
But a NULL return values 'guarantees' that memory is not available.
Ok, but what is your suggestion?
As I have written: The code calling some utility routine is in the
position to do something sensible about ENOMEM, even is this would
only be 'print a message an exit' (another option would be 'schedule a
retry using data structures pre-reserved for this operation'). But to
be able to do so, it must know about the failure first, instead of
just calling the subroutine-of-no-return and being slaughtered for
giddiness. The subroutine itself, except if it is only used in a
specific context, cannot know what to do in case of an error it cannot
recover from on its own.
Post by Syren Baran
Wrap every malloc like
if (!malloc(..)){
fprintf(stderr,"Out of memory!\n");
exit(1);
}
?
Checking every single malloc in a bigger application for possible
solutions to ENOMEM's is hardly feasible.
How big would the application still be, provided all superflouus
malloc calls would be removed?

Failure isn't necessarily an option.
Syren Baran
2008-01-25 08:58:18 UTC
Permalink
Post by Rainer Weikusat
Post by Syren Baran
Checking every single malloc in a bigger application for possible
solutions to ENOMEM's is hardly feasible.
How big would the application still be, provided all superflouus
malloc calls would be removed?
Thus i conclude you sparcely use malloc's. Probably just a few big
mallocs. Probably definately big enough. Thus probably a lot bigger than
actually required. Thus part of the reason linux overcommits memory.
Post by Rainer Weikusat
Failure isn't necessarily an option.
Ok, so you prefer arrays in stack space to dynamicly allocated pointers.
How do you proove that this stack space can be allocated?
Rainer Weikusat
2008-01-25 19:43:39 UTC
Permalink
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
Checking every single malloc in a bigger application for possible
solutions to ENOMEM's is hardly feasible.
How big would the application still be, provided all superflouus
malloc calls would be removed?
Thus i conclude you sparcely use malloc's.
Probably just a few big mallocs. Probably definately big
enough. Thus probably a lot bigger than actually required.
Thus part of the reason linux overcommits
I am not restriced to only doing things in ways you have already heard
of :->.
Post by Syren Baran
memory. Failure isn't necessarily an option.
Ok, so you prefer arrays in stack space to dynamicly allocated pointers.
How do you proove that this stack space can be allocated?
Let me ask a counter-question: Why do you continously try to change
the topic of the discusssion, instead of arguing against what I wrote?
Syren Baran
2008-01-26 12:18:29 UTC
Permalink
Post by Rainer Weikusat
Post by Syren Baran
Thus i conclude you sparcely use malloc's.
Probably just a few big mallocs. Probably definately big
enough. Thus probably a lot bigger than actually required.
Thus part of the reason linux overcommits
I am not restriced to only doing things in ways you have already heard
of :->.
Ok, so you actually do things right now and then?
Post by Rainer Weikusat
Post by Syren Baran
memory. Failure isn't necessarily an option.
Ok, so you prefer arrays in stack space to dynamicly allocated pointers.
How do you proove that this stack space can be allocated?
Let me ask a counter-question: Why do you continously try to change
the topic of the discusssion, instead of arguing against what I wrote?
The part i deleted in the last reply was far off. I mean a lot more
limited that being able to run a linux kernel, though not as limited as
old home computers i had.

How do you consider this changing topic? You argue that malloc has to be
checked while allocating arrays in stack space in fine. Thus you
obviously arent aware of the fact calling a function can fail in this
"doomsday scenario" which you imply.
Your "way" is thus no more safe than what i´m doing.
Also you replies were not in the least constructive, since you didnt
answer any questions but just choose bash my style.
Well, i remember the sentance "Sometimes those with the most sin throw
the first stones."
I´ll do some checks on the execution speed of malloc vs calling a
function with a stack spack array. So far that would be the only reason
i can see to change the code.
Rainer Weikusat
2008-01-27 11:35:12 UTC
Permalink
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
Thus i conclude you sparcely use malloc's.
Probably just a few big mallocs. Probably definately big
enough. Thus probably a lot bigger than actually required.
Thus part of the reason linux overcommits
I am not restriced to only doing things in ways you have already heard
of :->.
Ok, so you actually do things right now and then?
Dear Homer. In the given context, this sentence of yours means that
YOU (and that would be you) never do anything 'right', because YOU
(again meaning you) have really no idea how to. This was presumably
not what you intended to communicate, and you may thus want to keep
the reigns not controlling you zeal for blind opposition somewhat
shorter in future.

[...]
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
memory. Failure isn't necessarily an option.
Ok, so you prefer arrays in stack space to dynamicly allocated pointers.
How do you proove that this stack space can be allocated?
Let me ask a counter-question: Why do you continously try to change
the topic of the discusssion, instead of arguing against what I wrote?
The part i deleted in the last reply was far off.
It should have been easy to refute it then, don't you think so?
Post by Syren Baran
I mean a lot more limited that being able to run a linux kernel,
though not as limited as old home computers i had.
You mean 'some amount of RAM you consider to be very little, [although
it was actually plenty enough to run a JVM]'. And I meant (still)
'less RAM than would be needed for the system to work without
OOM-caused failures'. The difference would be the difference between
'enough' and 'not enough'. I was arguably imprecise when selecting the
initial wording, but since I have now explained this to you twice, you
can hardly claim that you still misunderstand me by accident.
Post by Syren Baran
How do you consider this changing topic?
Because of the changed topic, maybe?
Post by Syren Baran
You argue that malloc has to be checked while allocating arrays in
stack space in fine.
This is wrong. I have argued that the caller should be
able to allocate buffers in some convenient location the callee
cannot possibly know and (completely independent of this), that the
return values of calls which can fail, specifically, malloc, need to
be checked. You counterargument against the latter was 'this would
hardly be feasible in a large application' (depending on the person
using this adjective, this can mean anything between 100 and n * 10^6
lines of code) and I assume that the less-than-complimentary "I (here
refering to you) am much too lazy to write all this text" won't be
much 'off base' as an alternate description of the same phenomenon.
Since you couldn't possibly get away with that when there would be a
'high' chance of malloc actually failing, I further concluded that you
have never really been forced to deal with this possiblity.

Assuming this as given, your 'judgement' in this respect can hardly
be trusted, IOW 'there will always be an Escimo knowing exactly
how the inhabitants of the Kongo should deal with heat waves'.

[...]
Post by Syren Baran
Also you replies were not in the least constructive, since you didnt
answer any questions but just choose bash my style.
I simply refuse to follow you on your attempt to run in a circle with
a very high speed. If I refuted one of your points, you would leave
it and raise a different one, eventually ending up at the same point
where the 'discussion' started. This is useless, because they idea
behind a discussion is to determine (insofar possible) 'the truth' (or
at least the different aspects something can be viewed as) about some
phenomenon which can be described by combining observation, history
and reasoning, not 'who takes her home afterwards', if you understand
to what type of other quarrel I am alluding here.
Syren Baran
2008-01-27 15:13:40 UTC
Permalink
Post by Rainer Weikusat
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
Thus i conclude you sparcely use malloc's.
Probably just a few big mallocs. Probably definately big
enough. Thus probably a lot bigger than actually required.
Thus part of the reason linux overcommits
I am not restriced to only doing things in ways you have already heard
of :->.
Ok, so you actually do things right now and then?
Dear Homer. In the given context, this sentence of yours means that
YOU (and that would be you) never do anything 'right', because YOU
(again meaning you) have really no idea how to. This was presumably
not what you intended to communicate, and you may thus want to keep
the reigns not controlling you zeal for blind opposition somewhat
shorter in future.
I think i must have hit a soft spot. He is really is getting angry.
Post by Rainer Weikusat
[...]
Post by Syren Baran
The part i deleted in the last reply was far off.
It should have been easy to refute it then, don't you think so?
You could have as well quoted a verse from a childrens poem. It would
not have had less tpoicality than your reply.
Post by Rainer Weikusat
Post by Syren Baran
I mean a lot more limited that being able to run a linux kernel,
though not as limited as old home computers i had.
You mean 'some amount of RAM you consider to be very little, [although
it was actually plenty enough to run a JVM]'.
http://en.wikipedia.org/wiki/CLDC#Typical_requirements
Choose for yourself if you consider that limited or not.
And I meant (still)
Post by Rainer Weikusat
'less RAM than would be needed for the system to work without
OOM-caused failures'. The difference would be the difference between
'enough' and 'not enough'. I was arguably imprecise when selecting the
initial wording, but since I have now explained this to you twice, you
can hardly claim that you still misunderstand me by accident.
And there again there was no reason to check memory allocations (not
mallocs obviously) since the total amount of RAM was well known and the
underlying OS wasnt even multi-tasking capable.
Post by Rainer Weikusat
Post by Syren Baran
How do you consider this changing topic?
Because of the changed topic, maybe?
Maybe you didnt understand the connection?
Post by Rainer Weikusat
Post by Syren Baran
You argue that malloc has to be checked while allocating arrays in
stack space in fine.
This is wrong. I have argued that the caller should be
able to allocate buffers in some convenient location the callee
cannot possibly know
And my argument for not doing so has remained the same from the start. I
prefer to dynamicly allocate the memory than check for overruns every time.
and (completely independent of this), that the
Post by Rainer Weikusat
return values of calls which can fail, specifically, malloc, need to
be checked.
Ok, so lets assume a malloc(1) fails.
What does this mean?
The OS can not allocate a further page for the heap.
Further programm flow is no longer well defined, since every function
call might require allocating a page for the stack.
Is the above TRUE or FALSE?
After all you want to the discussion to lead to the discovery of the truth.

You counterargument against the latter was 'this would
Post by Rainer Weikusat
hardly be feasible in a large application'
Quoting myself:
" Checking every single malloc in a bigger application for possible
solutions to ENOMEM's is hardly feasible."
I stand to that.
Checking a large malloc, sure. Checking a small malloc, bullshit. Rather
catch SIGSEGV. That adds less overhead than a wrapper function for malloc.
(depending on the person
Post by Rainer Weikusat
using this adjective, this can mean anything between 100 and n * 10^6
lines of code) and I assume that the less-than-complimentary "I (here
refering to you) am much too lazy to write all this text" won't be
much 'off base' as an alternate description of the same phenomenon.
Since you couldn't possibly get away with that when there would be a
'high' chance of malloc actually failing, I further concluded that you
have never really been forced to deal with this possiblity.
Ok a high chance of malloc failing means allocating a "large" amount of
memory, right?
I never argued against that.
Post by Rainer Weikusat
Assuming this as given, your 'judgement' in this respect can hardly
be trusted, IOW 'there will always be an Escimo knowing exactly
how the inhabitants of the Kongo should deal with heat waves'.
I am not aware of any inuit who have written their doctorol thesis in
meteorology on that topic. But since i have no knowledge of that field
of study i can neither refute nor confirm that.
Post by Rainer Weikusat
[...]
Post by Syren Baran
Also you replies were not in the least constructive, since you didnt
answer any questions but just choose bash my style.
I simply refuse to follow you on your attempt to run in a circle with
a very high speed. If I refuted one of your points, you would leave
it and raise a different one, eventually ending up at the same point
where the 'discussion' started. This is useless, because they idea
behind a discussion is to determine (insofar possible) 'the truth' (or
at least the different aspects something can be viewed as) about some
phenomenon which can be described by combining observation, history
and reasoning, not 'who takes her home afterwards', if you understand
to what type of other quarrel I am alluding here.
Above i asked "Is the above TRUE or FALSE"?
You may now refute that point, agree or give me your alternative view of
that situation.
Rainer Weikusat
2008-01-27 15:35:37 UTC
Permalink
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
Thus i conclude you sparcely use malloc's.
Probably just a few big mallocs. Probably definately big
enough. Thus probably a lot bigger than actually required.
Thus part of the reason linux overcommits
I am not restriced to only doing things in ways you have already heard
of :->.
Ok, so you actually do things right now and then?
Dear Homer. In the given context, this sentence of yours means that
YOU (and that would be you) never do anything 'right', because YOU
(again meaning you) have really no idea how to. This was presumably
not what you intended to communicate, and you may thus want to keep
the reigns not controlling you zeal for blind opposition somewhat
shorter in future.
I think i must have hit a soft spot. He is really is getting angry.
You managed to accidentally write that you consider yourself to be an
idiot. That's no reason for me to be angry. It's laughable.
Rainer Weikusat
2008-01-27 18:31:16 UTC
Permalink
[...]
Post by Syren Baran
http://en.wikipedia.org/wiki/CLDC#Typical_requirements
Choose for yourself if you consider that limited or not.
See (second) explanation below of what I was refering too (which you
have now completey ignored for the second time).
Post by Syren Baran
And I meant (still) 'less RAM than would be needed for the system
to work without OOM-caused failures'. The difference would be the
difference between 'enough' and 'not enough'. I was arguably
imprecise when selecting the initial wording, but since I have now
explained this to you twice, you can hardly claim that you still
misunderstand me by accident.
And there again there was no reason to check memory allocations (not
mallocs obviously) since the total amount of RAM was well known and
the underlying OS wasnt even multi-tasking capable.
This doesn't refer to my text above anyhow.

[...]
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
You argue that malloc has to be checked while allocating arrays in
stack space in fine.
This is wrong. I have argued that the caller should be
able to allocate buffers in some convenient location the callee
cannot possibly know
And my argument for not doing so has remained the same from the
start. I prefer to dynamicly allocate the memory than check for
overruns every time.
There is no reference to the caller/ callee issue I mentioned in you
text. Indepedently of this, it doesn't make sense: A size is need to
dynamically allocate a block of memory and computing this size to use
it for an allocation isn't anyhow different than computing the same
size and use it to compare with some other size. The caller can, of
course, dynamically allocate the buffer somewhere too and interface
enabling this, eg snprintf, have already been mentioned in this text.
Post by Syren Baran
and (completely independent of this), that the return values of
calls which can fail, specifically, malloc, need to be checked.
Ok, so lets assume a malloc(1) fails. What does this mean?
The OS can not allocate a further page for the heap. Further
programm flow is no longer well defined, since every function
call might require allocating a page for the stack.
Is the above TRUE or FALSE?
It's trash. Eg, on Linux 2.4, some mallocs fail when the maximum
amount of sbreakable space has been exceeded, ie the break has been
moved up to the so-called 'unmapped base' of a task, despite the fact
that there is still plenty free RAM available and that the stack,
sitting in a completely different part of the address space, can still
be expanded. The amount of stack space needed is bound by the maximum
possible callchain depth of some program, including all automatic
allocations needed along this callchain. The memory needed for this is
shared among all possible callchains. This means that once the maximum
callchain depth has been reached once, the stack will not grow
anymore. Depending on the application, stacks possibly don't
grow at all, but are preallocated (multi-threading). The Linux kernel
can, for instance, be configured to use only a 4K kernel stack per
thread and doesn't have any stack overrun checking (AFAIK), suggesting
that requirements for stack memory are really modest, even in 'large'
programs. That they actually are can be verified, eg, by running pmap
on a few long-running processes on some Linux systems.

Ignoring the factual errors in your statement, that operation X could
fail, too, is not an argument for ignoring possible failures of
operation Y. And we were discussing Y and not X.
Post by Syren Baran
After all you want to the discussion to lead to the discovery of the truth.
And the truth is that you have no clue about what you are talking
about. Not that anybody could possibly have guessed that ...
Post by Syren Baran
You counterargument against the latter was 'this would
Post by Rainer Weikusat
hardly be feasible in a large application'
" Checking every single malloc in a bigger application for possible
solutions to ENOMEM's is hardly feasible."
I stand to that.
Checking a large malloc, sure. Checking a small malloc,
bullshit. Rather catch SIGSEGV. That adds less overhead than a wrapper
function for malloc.
The behaviour of a program which has caught SIGSEGV and the signal
handler has returned is undefined for UNIX(*). Restateting that you
rather rely on the availability of RAM and accept that the program may
'crash' because it wasn't doesn't make this a more sensible strategy
to cope with actual ressource shortage (remember the scheduled retry)
than it was last time.
Post by Syren Baran
(depending on the person
Post by Rainer Weikusat
using this adjective, this can mean anything between 100 and n * 10^6
lines of code) and I assume that the less-than-complimentary "I (here
refering to you) am much too lazy to write all this text" won't be
much 'off base' as an alternate description of the same phenomenon.
Since you couldn't possibly get away with that when there would be a
'high' chance of malloc actually failing, I further concluded that you
have never really been forced to deal with this possiblity.
Ok a high chance of malloc failing means allocating a "large" amount
of memory, right?
Why would it?
Post by Syren Baran
Post by Rainer Weikusat
Assuming this as given, your 'judgement' in this respect can hardly
be trusted, IOW 'there will always be an Escimo knowing exactly
how the inhabitants of the Kongo should deal with heat waves'.
I am not aware of any inuit who have written their doctorol thesis in
meteorology on that topic. But since i have no knowledge of that field
of study i can neither refute nor confirm that.
Translating this into simpler language: Opinions are like
a*holes. Everybody has one.

Got it this time?
Syren Baran
2008-01-27 20:43:21 UTC
Permalink
Post by Rainer Weikusat
Post by Syren Baran
http://en.wikipedia.org/wiki/CLDC#Typical_requirements
Choose for yourself if you consider that limited or not.
See (second) explanation below of what I was refering too (which you
have now completey ignored for the second time).
Ok, our definitions of "memory limited" differ.
Post by Rainer Weikusat
Post by Syren Baran
And I meant (still) 'less RAM than would be needed for the system
to work without OOM-caused failures'. The difference would be the
difference between 'enough' and 'not enough'.
I dont know which world you live in. You design every program with
"there wont be enough memory anyway" in mind?
Post by Rainer Weikusat
Post by Syren Baran
And there again there was no reason to check memory allocations (not
mallocs obviously) since the total amount of RAM was well known and
the underlying OS wasnt even multi-tasking capable.
This doesn't refer to my text above anyhow.
No, but it does refer to your "you need to check every memory
allocation". Sorry, you wrote malloc, not memory allocation.
But my point simply is, that is not allways the case.
Post by Rainer Weikusat
[...]
Post by Syren Baran
Post by Rainer Weikusat
Post by Syren Baran
You argue that malloc has to be checked while allocating arrays in
stack space in fine.
This is wrong. I have argued that the caller should be
able to allocate buffers in some convenient location the callee
cannot possibly know
And my argument for not doing so has remained the same from the
start. I prefer to dynamicly allocate the memory than check for
overruns every time.
There is no reference to the caller/ callee issue I mentioned in you
text.
Right. There is no reference. Because i do it differently.
Indepedently of this, it doesn't make sense: A size is need to
Post by Rainer Weikusat
dynamically allocate a block of memory and computing this size to use
it for an allocation isn't anyhow different than computing the same
size and use it to compare with some other size. The caller can, of
course, dynamically allocate the buffer somewhere too and interface
enabling this, eg snprintf, have already been mentioned in this text.
Now you are running in circles. If the buffer isnt big enough i have to
allocate a new buffer anyway.
Post by Rainer Weikusat
Post by Syren Baran
and (completely independent of this), that the return values of
calls which can fail, specifically, malloc, need to be checked.
Ok, so lets assume a malloc(1) fails. What does this mean?
The OS can not allocate a further page for the heap. Further
programm flow is no longer well defined, since every function
call might require allocating a page for the stack.
Is the above TRUE or FALSE?
It's trash. Eg, on Linux 2.4, some mallocs fail when the maximum
[lots snipped]
Ok, so your programms continue their if work malloc(1) fails.
If you have enough confidence in your skill, then do so.
I wont.
Post by Rainer Weikusat
Ignoring the factual errors in your statement, that operation X could
fail, too, is not an argument for ignoring possible failures of
operation Y. And we were discussing Y and not X.
If X fails the situation is too fubar'd to continue with Y. YMMV.
Post by Rainer Weikusat
Post by Syren Baran
After all you want to the discussion to lead to the discovery of the truth.
And the truth is that you have no clue about what you are talking
about. Not that anybody could possibly have guessed that ...
Well, i´ll just stick to your comment on opinions your wrote further below.
Post by Rainer Weikusat
Post by Syren Baran
" Checking every single malloc in a bigger application for possible
solutions to ENOMEM's is hardly feasible."
I stand to that.
Checking a large malloc, sure. Checking a small malloc,
bullshit. Rather catch SIGSEGV. That adds less overhead than a wrapper
function for malloc.
The behaviour of a program which has caught SIGSEGV and the signal
handler has returned is undefined for UNIX(*).
Did i say ANYTHING about returning from SIGSEGV?
Going down in a recoverable manner, sure. But i assume you even take
into consideration there may be no disk space available.
Restateting that you
Post by Rainer Weikusat
rather rely on the availability of RAM and accept that the program may
'crash' because it wasn't doesn't make this a more sensible strategy
to cope with actual ressource shortage (remember the scheduled retry)
than it was last time.
I just accept that the situation may be too fubar´d to continue.
Obviously you dont.
If you trust your skills enough to continue operation in the discussed
situation (malloc(1) fails), do so. I prefer a clean exit.
Post by Rainer Weikusat
Post by Syren Baran
Ok a high chance of malloc failing means allocating a "large" amount
of memory, right?
Why would it?
The probability of malloc(n) failing reaches certainty for for n->oo .
Post by Rainer Weikusat
Post by Syren Baran
Post by Rainer Weikusat
Assuming this as given, your 'judgement' in this respect can hardly
be trusted, IOW 'there will always be an Escimo knowing exactly
how the inhabitants of the Kongo should deal with heat waves'.
I am not aware of any inuit who have written their doctorol thesis in
meteorology on that topic. But since i have no knowledge of that field
of study i can neither refute nor confirm that.
Translating this into simpler language: Opinions are like
a*holes. Everybody has one.
Got it this time?
I accept the fact you have an aeh opinion.

Spoon
2008-01-23 12:29:52 UTC
Permalink
I wrote this helper function. But somehow I can't help the feeling
it's a bit kludgy. Any suggestions for improvement (aside from the
fact it doesn't handle max-negative-value correctly)?
#include <stdio.h>
#include <stdlib.h>
const int MAX = 20;
char *itoa(int src)
{
char *res = malloc(MAX);
if (res) snprintf(res, MAX, "%d", src);
return res;
}
Loading...