Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare C pointers?

Tags:

c

pointers

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) 
like image 507
jiych.guru Avatar asked Jul 11 '13 03:07

jiych.guru


People also ask

How do I compare the contents of two pointers?

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.

How do you compare integers and pointers?

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" .

What are the different relational operators that can be used to compare pointers?

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.


1 Answers

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.

like image 52
ruakh Avatar answered Oct 06 '22 11:10

ruakh