Re: Inconsistent Program Results



I hadn't expected such detailed replies... it seems that in fact it
was just a silly oversight, and adding if(restrict) above the printf
statement was all I needed to do to get things working, but I'm very
grateful to those who made detailed comments on other parts of my code
too. I'm definitely going to take them on board - I'm trying to learn
C in an accelerated way at the moment, and these concentrated comments
are really helpful.

#include <malloc.h>

Replace this with <stdlib.h> which is the standard header you need when
using malloc.

I think what happens is that stdlib is modularized, and all the
allocation functions are in malloc.h, so just including this avoids
bloating the compiled executable with extraneous cruft from stdlib.

#include <memory.h>

Replace this with <string.h> which is the standard header you need when
using strchr.

OK, though on my system memory.h just does #include <string.h> anyway.

void rdinpt();

Make this:

void rdinput(char **);

I don't think it's obligatory to list the parameters yet is it?

Incidentally, readinput would have been a better name.

Sounds like more typing :(

void main()

Make this:

int main(void)

What's the advantage to this? In my textbook, main only returns int if
the return value is significant for something (e.g. if main is called
recursively).

char *s, *restrict;
rdinpt(&s);
restrict=strchr(s,' ');

If the malloc fails, s will have the value NULL, which is not legal for
passing to strchr.

If there is no space in the input string, strchr will return NULL, which
you must not pass to printf to match %s, and which you must not
increment.

Understood - thanks.

free(s), s=restrict=0;

This made me reach for the book. Simplify:

free(s);
s = restrict = 0;

I think the comma is useful because it shows that there's one
conceptual operation (free a pointer and remove bogus references),
which gets broken up if you use two separate statements.

*s=(char *) malloc( (unsigned int) LEN);

Better:

*s = malloc(LEN * sizeof **s);

Well, OK, if you know that char * and void * have the same internal
representation, but as I understand it you'd still need to typecase if
*s was an int * for the sake of alignment.

(void) gets(*s);

Avoid gets() - it cannot be used safely. Instead, use:

I read the man page for gets, and it does seem that in production code
it should be avoided. But for a little program, 1000 bytes is already
a conservative buffer size.

return(0);

Remove this, since rdinpt doesn't return a value.

Thanks, I always forget whether to return() or return(0) at the end of
a void function.

}

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.

.



Relevant Pages

  • Re: regarding * and ++ operators
    ... a void * when printing a pointer value. ... the printf() statement. ... and let us say "int" occupies 4 bytes. ...
    (comp.lang.c)
  • Re: pointer question
    ... void f ... I'm trying to get the printf to print hello, but I tried memcpy(*c, ... int main ... char *c = NULL; ...
    (comp.lang.c)
  • Re: get the address of a function??
    ... void hello ... Calling printf with no visible prototype invokes undefined behavior. ... Make it "int main". ... *But* there's no defined conversion from a function pointer to void* ...
    (comp.lang.c)
  • Re: Can Someone please help?
    ... int main ... void Compute ... printf; ... Tim ...
    (comp.lang.c)
  • Re: Can somebody help...
    ... a number of unsafe constructs and non-standard extensions. ... That value is too large to portably store in an int. ... This results in undefined behavior because you lied to printf about what ...
    (comp.lang.cpp)