Home > Software design >  Pointers comparison
Pointers comparison

Time:09-09

I am writing a program that simulates the race between the tortoise and the hare.

They both move along two distinct one-dim array of 70 elements and, of course, since they move forward and backward they might wind up beyond the element 0 or 69.

I want to use pointers comparison to check if they did, so here comes the question:

i know that pointers comparison is legit if we are comparing pointers that point to elements of the same array, because otherwise we can't be sure of their position in memory; still, suppose we have:

char arr[70];
char *p1 = &arr[0]
char *p2 = &arr[69]

can't we be sure that p1 > p1 - 3 and p2 < p2 6 , because, in this case, the addresses will be contiguous? We know for certain which comes first and whatnot, right?

I did various tests and it appears to be so, but i wanted to be sure.

CodePudding user response:

No. It is only valid to compare pointers which point to an element within an array object or one past the end of the array object. But there is another problem here.

As they are defined above (p1 pointing to the first element of arr and p2 pointing to the last element of arr), you might think that attempting to dereference p1 - 3 or p2 6 would lead to undefined behavior; but even attempting to form the addresses p1 - 3 or p2 6 by using pointer arithmetic leads to undefined behavior, so the program is invalid the moment this pointer arithmetic is attempted. You can use pointer arithmetic to form an address that is within the array object, or one past the end of the array object. No other addresses may be formed from a pointer to an element of the array using pointer arithmetic.

CodePudding user response:

can't we be sure p1 > p1 - 3

theoretically, no, because of unsigned integer / pointer wraparound in C.

Practically, we can be sure – arr would never end up beginning at an address <= 3, so that subtracting 3 ends up unsigned-integer-wrapping around.

p2 < p2 6

Same as above, but positive integer wrap around. The last address of arr's memory region will not be less than 6 bytes from the end of the memory region.

Note, however, that dereferencing (i.e., *(p1-3), *(p2 6)) is undefined behaviour, since there's no memory there that you allocated. It might very well cause a segfault, read some other data, or trigger a stack protection canary. Whatever, actually, it might set your house on fire, which is a valid thing for the compiler to cause your program to do when you invoke undefined behaviour.

  • Related