Recently, I wrote some code to compare pointers like this:
if(p1+len < p2)
however, some staff said that I should write like this:
if(p2-p1 > len)
to be safe. Here,p1 and p2 are char *
pointers,len is an integer. I have no idea about that.Is that right?
EDIT1: of course,p1 and p2 pointer to the same memory object at begging.
EDIT2:just one min ago,I found the bogo of this question in my code(about 3K lines),because len
is so big that p1+len
can't store in 4 bytes of pointer,so p1+len < p2 is true.But it shouldn't in fact,so I think we should compare pointers like this in some situation:
if(p2 < p1 || (uint32_t)p2-p1 > (uint32_t)len)
When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object, or both point one past the last element of the same array object, they compare equal.
Also note that in your comparison *s == "a" it is actually the "a" which is the pointer, and *s which is the integer... The * dereferences s , which results in the char (an integer) stored at the address pointed to by s . The string literal, however, acts as a pointer to the first character of the string "a" .
Both operands of any relational or equality operator can be pointers to the same type. For the equality ( == ) and inequality ( != ) operators, the result of the comparison indicates whether the two pointers address the same memory location.
In general, you can only safely compare pointers if they're both pointing to parts of the same memory object (or one position past the end of the object). When p1
, p1 + len
, and p2
all conform to this rule, both of your if
-tests are equivalent, so you needn't worry. On the other hand, if only p1
and p2
are known to conform to this rule, and p1 + len
might be too far past the end, only if(p2-p1 > len)
is safe. (But I can't imagine that's the case for you. I assume that p1
points to the beginning of some memory-block, and p1 + len
points to the position after the end of it, right?)
What they may have been thinking of is integer arithmetic: if it's possible that i1 + i2
will overflow, but you know that i3 - i1
will not, then i1 + i2 < i3
could either wrap around (if they're unsigned integers) or trigger undefined behavior (if they're signed integers) or both (if your system happens to perform wraparound for signed-integer overflow), whereas i3 - i1 > i2
will not have that problem.
Edited to add: In a comment, you write "len
is a value from buff, so it may be anything". In that case, they are quite right, and p2 - p1 > len
is safer, since p1 + len
may not be valid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With