P
Peter J. Holzer
main(argc, argv)
int argc; char **argv;
{
char *strtrim(), *r=0;
puts(argc>1 && (r=strtrim(*++argv)) ? r : "Unspecified error");
free(r);
}
/* trims initial whitespace */
char *strtrim(s)
char *s;
{
char *r, *malloc(), *strcpy();
for( ; isspace(*s); s++);
r=malloc(strlen(s)+1);
if(r)
strcpy(r,s);
return r;
}
[...]
On the contrary, I've declared malloc correctly
No, you haven't.
and store its return value in a char *.
I'm not sure what to do about people's advice that some of the syntax in
the lecture notes is now old-fashioned - as it still seems to compile
just fine, I'm tempted to stick with what I know.
It *seems* to compile fine. It also *seems* to execute fine on your
system. But it's still wrong, and works only by chance. It may not work
on a different system.
For example, you haven't defined strlen, so the compiler has to assume
it returns an int. But it returns a size_t and a size_t may be returned
differently than an int (for example, on the 8086, in some memory
models, a size_t was returned in a pair of registers, but an int in only
one register. Declaring strlen as an int instead of a size_t would yield
wrong results if the string was longer than 32767 characters).
Then you pass the int which is the result of strlen(s)+1 to malloc.
Since no prototype is in scope, the compiler has to assume that malloc
expects an int, when really it expects a size_t. Using the example of
the 8086 compiler again, malloc would take 4 bytes off the stack, but
strtrim put only 2 bytes there, so the other two bytes contain some
random garbage (maybe the uninitialized value of r, or a part of the
value of s from the call to isspace). So malloc may try to allocate some
ridiculous amount of memory (basically rand() * 65536 + strlen(s)+1) and
fail. So strtrim also fails.
(This is harder to demonstrate with 64 bit processors: The calling
convention for x86_64 is to pass the first 6 parameters in registers, so
an int/size_t mismatch matters only if it happens in 7th or later
parameter. But assuming you can be sloppy if you only have functions
with 6 or less parameters sounds like an extremely bad idea to me)
As an erstwhile regular in this group wrote: "If you lie to the compiler
it will get its revenge!"
hp