Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Is My Program OK?

Reply
Thread Tools

Is My Program OK?

 
 
kooladi
Guest
Posts: n/a
 
      02-27-2008
On Feb 27, 1:59 pm, santosh <(E-Mail Removed)> wrote:
> jaysome wrote:
> > On Tue, 26 Feb 2008 15:19:33 -0500, Kenneth Brody
> > <(E-Mail Removed)> wrote:

>
> >>CBFalconer wrote:

>
> >>> Kenneth Brody wrote:
> >>> > (E-Mail Removed) wrote:
> >>[... size needed for "%p" output ...]
> >>> >> You *cannot* know the size.

>
> >>> > <pedant>
> >>> > Well, you can "know" it at runtime, with snprintf():

>
> >>> > 7.19.6.5p3

>
> >>> > The snprintf function returns the number of characters that
> >>> > would have been written had n been sufficiently large, not
> >>> > counting the terminating null character, or a negative value
> >>> > if an encoding error occurred.
> >>> > </pedant>

>
> >>> The C standard for fprintf says:
> >>[... returns length or negative for error ...]
> >>> and for printf says:
> >>[... returns length or negative for error ...]
> >>> which seem to provide an adequate means of determining the size
> >>> written. Similarly for sprintf. Amazingly enough, these also
> >>> allow detecting i/o errors in the output stream.

>
> >>But, how big should you make the buffer for sprintf(), as the OP
> >>was using?

>
> > The C Standard says this about the "%p" conversion specification:

>
> > "The argument shall be a pointer to void. The value of the pointer is
> > converted to a sequence of printing characters, in an
> > implementation-defined manner."

>
> > This means that this program:

>
> > #include <stdio.h>
> > int main(void)
> > {
> > printf("%p\n", (void*)0);
> > return 0;
> > }

>
> > can produce the following output in a strictly conforming
> > implementation:

>
> > The quick brown fox jumps over the lazy dog.

>
> > It could also output the text of The Declaration of Independence or of
> > the book War and Peace. In other words, strictly speaking, the answer
> > to the OP's question is: we don't know and we can't say.

>
> > Practically speaking, though, a buffer size that is a generous power
> > of 2 will work. I'd be comfortable with s[16], but personally I'd use
> > a very cheap s[32] just for good measure.

>
> > In my experience, sprintf'ing a pointer value to a string (in, for
> > example, a debug log message), requires that you use a size for the
> > string that is sufficient in size by eyeballing it. For example:

>
> > char s[128];
> > sprintf("p is %p\n", (void*)p);

>
> > Although the size 128 is, strictly speaking, not guaranteed to be
> > sufficient in size to accomodate the "%p" conversion specification
> > along with the accompanying text, it is sufficient for practical
> > purposes, all things considered.

>
> I suppose the proper way to do this is:
>
> char *ptr = "hello";

Shouldnt this be const char* ptr="hello";

> char *a;
> int n = snprintf(NULL, 0, "%p", ptr);
> if (n > 0) {
> a = malloc(n + 1);
> if (!a) exit(EXIT_FAILURE);
> else {
> int m;
> m = snprintf(a, n + 1, "%p", ptr);
> if (m < 0 || m < n) {
> /* error */
> }
> }}
>
> else /* error */


 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      02-27-2008
santosh said:

> jaysome wrote:
>

<snip>

>> Although the size 128 is, strictly speaking, not guaranteed to be
>> sufficient in size to accomodate the "%p" conversion specification
>> along with the accompanying text, it is sufficient for practical
>> purposes, all things considered.

>
> I suppose the proper way to do this is:
>
> char *ptr = "hello";
> char *a;
> int n = snprintf(NULL, 0, "%p", ptr);


It can, of course, be done without snprintf, for those who must avoid that
function for portability reasons - albeit not terribly elegantly. The
obvious way is to use a temporary file and fprintf:

int n = 0;
FILE *fp = tmpfile();
if(tmpfile != NULL)
{
n = fprintf(fp, "%p", (void *)ptr);
fclose(fp);
}
if(n > 0)
{
n + 1 tells us how many bytes to malloc for the string.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
 
 
 
Kenneth Brody
Guest
Posts: n/a
 
      02-27-2008
jaysome wrote:
>
> On Tue, 26 Feb 2008 15:19:33 -0500, Kenneth Brody
> <(E-Mail Removed)> wrote:
>
> >CBFalconer wrote:
> >>
> >> Kenneth Brody wrote:
> >> > http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> >[... size needed for "%p" output ...]
> >> >> You *cannot* know the size.
> >> >
> >> > <pedant>
> >> > Well, you can "know" it at runtime, with snprintf():
> >> >
> >> > 7.19.6.5p3
> >> >
> >> > The snprintf function returns the number of characters that
> >> > would have been written had n been sufficiently large, not
> >> > counting the terminating null character, or a negative value
> >> > if an encoding error occurred.
> >> > </pedant>
> >>
> >> The C standard for fprintf says:

> >[... returns length or negative for error ...]
> >> and for printf says:

> >[... returns length or negative for error ...]
> >> which seem to provide an adequate means of determining the size
> >> written. Similarly for sprintf. Amazingly enough, these also
> >> allow detecting i/o errors in the output stream.

> >
> >But, how big should you make the buffer for sprintf(), as the OP
> >was using?

>
> The C Standard says this about the "%p" conversion specification:
>
> "The argument shall be a pointer to void. The value of the pointer is
> converted to a sequence of printing characters, in an
> implementation-defined manner."
>
> This means that this program:
>
> #include <stdio.h>
> int main(void)
> {
> printf("%p\n", (void*)0);
> return 0;
> }
>
> can produce the following output in a strictly conforming
> implementation:
>
> The quick brown fox jumps over the lazy dog.

[...]
> Although the size 128 is, strictly speaking, not guaranteed to be
> sufficient in size to accomodate the "%p" conversion specification
> along with the accompanying text, it is sufficient for practical
> purposes, all things considered.


Or, you could do as I pointed out -- use snprintf() to tell you how
long the output will be. (Something which can't be done with CBF's
suggestion of fprintf/printf/sprintf, since those will only tell you
after the fact, not before.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <(E-Mail Removed)>


 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      02-27-2008
Kenneth Brody wrote:
>

.... snip ...
>
> Or, you could do as I pointed out -- use snprintf() to tell you
> how long the output will be. (Something which can't be done
> with CBF's suggestion of fprintf/printf/sprintf, since those
> will only tell you after the fact, not before.)


Or you can design code with one of my favorite tricks - if the
destination is NULL do everthing, and return the result, without
actually outputting anything. That way the equivalent of
"fprintf(NULL, ...)" would return the size required.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      02-27-2008
CBFalconer wrote:

> Willem wrote:
>> CBFalconer wrote:
>>
>>> The C standard for fprintf says:

>> <snip> (returns the number printed, or negative)
>>> and for printf says:

>> <snip>
>>> which seem to provide an adequate means of determining the size
>>> written. Similarly for sprintf.

>>
>> Indeed, you can check that sprintf has gone beyond the bounds of
>> your buffer. _After_ it has clobbered whatever happened to be
>> located behind it (or invoked some other form of UB). Oopsie.

>
> You can know in advance the max length of most fields to be
> written. For strings, you can apply strlen. If you have room to
> absorb the max, you can always measure what was actually emitted.


Yes, but the case in question involves finding out how many characters
would be emitted for a pointer value printed out with the %p specifier,
which the Standard doesn't say anything about.

The easiest way to do this without any I/O at all is with snprintf.
Otherwise Richard's solution involving a temporary file and fprintf is
neat as well, since a file cannot (practically) cause a buffer
overflow. It *could* fill up the disk, but it will be immediately
deleted after storing and checking fprintf's return value.

The other option is to print the pointer value as an array of unsigned
char.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-27-2008
CBFalconer <(E-Mail Removed)> writes:
> Kenneth Brody wrote:
> ... snip ...
>>
>> Or, you could do as I pointed out -- use snprintf() to tell you
>> how long the output will be. (Something which can't be done
>> with CBF's suggestion of fprintf/printf/sprintf, since those
>> will only tell you after the fact, not before.)

>
> Or you can design code with one of my favorite tricks - if the
> destination is NULL do everthing, and return the result, without
> actually outputting anything. That way the equivalent of
> "fprintf(NULL, ...)" would return the size required.


Just what did you vahe in mind as being equivalent to
"fprintf(NULL, ...)"? It would be nice if fprintf worked that way,
but it doesn't.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Kenneth Brody
Guest
Posts: n/a
 
      02-27-2008
Keith Thompson wrote:
>
> CBFalconer <(E-Mail Removed)> writes:
> > Kenneth Brody wrote:
> > ... snip ...
> >>
> >> Or, you could do as I pointed out -- use snprintf() to tell you
> >> how long the output will be. (Something which can't be done
> >> with CBF's suggestion of fprintf/printf/sprintf, since those
> >> will only tell you after the fact, not before.)

> >
> > Or you can design code with one of my favorite tricks - if the
> > destination is NULL do everthing, and return the result, without
> > actually outputting anything. That way the equivalent of
> > "fprintf(NULL, ...)" would return the size required.

>
> Just what did you vahe in mind as being equivalent to
> "fprintf(NULL, ...)"? It would be nice if fprintf worked that way,
> but it doesn't.


What's wrong with "snprintf(NULL,0,...)", which does exactly what
we are trying to accomplish -- determine how long the output would
be if it were actually output?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <(E-Mail Removed)>


 
Reply With Quote
 
William Pursell
Guest
Posts: n/a
 
      02-27-2008
On Feb 27, 8:59 am, santosh <(E-Mail Removed)> wrote:
> jaysome wrote:


> > The C Standard says this about the "%p" conversion specification:

>
> > "The argument shall be a pointer to void. The value of the pointer is
> > converted to a sequence of printing characters, in an
> > implementation-defined manner."



Is there a guarantee that two calls to printf will produce
the same output? IOW, if we follow santosh's suggestion of:

> char *ptr = "hello";
> char *a;
> int n = snprintf(NULL, 0, "%p", ptr);
> if (n > 0) {
> a = malloc(n + 1);
> if (!a) exit(EXIT_FAILURE);
> else {
> int m;
> m = snprintf(a, n + 1, "%p", ptr);
> if (m < 0 || m < n) {
> /* error */
> }
> }}


Is there any guarantee that n + 1 is enough?
Perhaps the first snprintf returns enough space
to write "the quick brown fox", but the
second attempts to print the Declaration of
Independence.
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      02-27-2008
Keith Thompson wrote:
> CBFalconer <(E-Mail Removed)> writes:
>> Kenneth Brody wrote:
>> ... snip ...
>>>
>>> Or, you could do as I pointed out -- use snprintf() to tell you
>>> how long the output will be. (Something which can't be done
>>> with CBF's suggestion of fprintf/printf/sprintf, since those
>>> will only tell you after the fact, not before.)

>>
>> Or you can design code with one of my favorite tricks - if the
>> destination is NULL do everthing, and return the result, without
>> actually outputting anything. That way the equivalent of
>> "fprintf(NULL, ...)" would return the size required.

>
> Just what did you vahe in mind as being equivalent to
> "fprintf(NULL, ...)"? It would be nice if fprintf worked that
> way, but it doesn't.


Something you write. Imagine:

size_t foo(/* things */, FILE *f) {
....
if (f) err |= putc(f);
...
return something;
}

I have some routines to convert numbers to chars so written.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Bartc
Guest
Posts: n/a
 
      02-28-2008

"William Pursell" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On Feb 27, 8:59 am, santosh <(E-Mail Removed)> wrote:
>> jaysome wrote:

>
>> > The C Standard says this about the "%p" conversion specification:

>>
>> > "The argument shall be a pointer to void. The value of the pointer is
>> > converted to a sequence of printing characters, in an
>> > implementation-defined manner."

>
>
> Is there a guarantee that two calls to printf will produce
> the same output? IOW, if we follow santosh's suggestion of:
>

....
>
> Is there any guarantee that n + 1 is enough?
> Perhaps the first snprintf returns enough space
> to write "the quick brown fox", but the
> second attempts to print the Declaration of
> Independence.


They have to be the same. If not then it makes printing %p more or less
impossible in a reliable way.

Unless you print to a file first, but that starts becoming a crazy way to do
this.

The standard should have specified an upper limit for %p format length.

--
Bart


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to javac a java program w/ another java program which is w/o a main method cjeffwang@yahoo.com Java 1 10-31-2005 04:25 AM
System program/ Application program ?? Parvsandhu Java 2 07-11-2005 09:08 AM
how to convert a java program to an exe program ola Java 3 02-16-2004 09:42 AM
Calling Java program in another Java program Rey Java 4 12-12-2003 10:18 PM
passing data between Java program and C program--help pipi Java 1 07-21-2003 05:02 AM



Advertisments