"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > writes:
Method Man wrote:
Say I have the following:
#include <stdlib.h> int main(int argc, char* argv[]) {
char* p = (char*)malloc(s izeof(char)*10) ;
char* q = (p + 100) - 99; // illegal!
free(q - 1); // illegal!
// ....
return 0;
}
Will this program always produce UB?
This is an improper question.
Undefined Behavior (UB) is undefined.
There is no specific behavior to "produce".
Always work?
It works everywhere.
Or is it compiler dependent?
There are no ANSI/ISO C99 compliant compilers
that will not accept this code
and generate the expected output.
Tisdale has lied to us yet again. The code quoted above is not what
Method Man wrote. It's obvious that Tisdale isn't going to respond to
complaints, so I'll just post this as a warning to others.
The actual code was:
] int main(void) {
] char* p, q;
] p = (char*) malloc(sizeof(c har)*10);
] q = (p + 100) - 99; /* legal? */
] free(q - 1); /* legal? */
] ....
] return 0;
] }
Method Man's code had serious error: "char *p, q;" declares p as a
pointer to char, and q as a char. Tisdale, for some unfathomable
reason, decided to quietly pretend the error didn't exist rather than
tell Method Man about it.
(Note to Mabden: Based on your past behavior I expect you'll jump in
and flame me for calling Tisdale on his lie. I know your opinion on
the matter and I'm really not interested in hearing about it again.)
Assuming the declaration is corrected to
char *p, *q;
the evaluation of p + 100 invokes undefined behavior, because it
yields a value outside the bounds of the memory allocated by malloc().
Once undefined behavior is invoked, all bets are off.
If you change the statement
q = (p + 100) - 99;
to
q = (p + 10) - 9;
there's no problem; p+10 points just past the last element of the
allocated memory (which is ok as long as you don't dereference it),
and q then points to p[1]. q - 1 is then equal to p, and passing that
value to free() is valid.
Will it "work"? Quite possibly. The possible consequences of
undefined behavior always include behaving just as you expect
(assuming you have any expectation). It may or may not be the case
that the code "works" in all existing implementations , but a
bounds-checking implementation with fat pointers could easily trap.
The only sensible thing to do is avoid the undefined behavior in the
first place.
--
Keith Thompson (The_Other_Keit h)
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.