Why do these two pointer subtractions give different results?

Consider the following code:

char* p = new char[2]; long* pi = (long*) p; assert(p == pi); // OK char* p1 = &p[1]; long* pi1 = (long*) p1; assert(p1 == pi1); // OK int d = p1 - p; int d1 = pi1 - pi; assert(d == d1); // No :( 

After that, I get d == 1 and d1 == 0 , although p1 == pi1 and p == pi (I checked this in the debugger). Is this behavior undefined?

+7
source share
4 answers

As others have pointed out, this behavior is undefined. However, there is a very simple explanation for what you see.

The difference between pointers is the number of elements, not the number of bytes between them.

pi and pi1 point to longs, but the address that pi1 points to is only one byte, except for pi. Assuming longs is 4 bytes long, the difference in addresses 1 divided by the size of element 4 is 0.

Another way to think about what you could imagine is that the compiler would generate code equivalent to this for computing d1:

 int d1 = ((BYTE*)pi1 - (BYTE*)pi)/sizeof(long). 
+10
source

The difference between the two pointers is undefined if the pointers do not point to the same array, or the pointers were pointed from pointers to an unrelated type.

In addition, the difference is not in bytes, but in the number of elements.

In your second case, the difference is 1 byte, but it is divided by sizeof (long). Please note that since this behavior is undefined, absolutely any answer here will be correct.

+5
source

Interpretation of the base type of the pointer does not change its address. But pointer arithmetic gives different results depending on the type of pointer. So, what you described here is completely correct, and that is what I was expecting. See pointer arithmetic .

+2
source

Performing integer (long) pointer arithmetic for pi1 - pi ;

If p1 were &p[4] , you will see that it prints 1 for d1 , while the difference is actually 4 bytes. This is because sizeof (long) = 4 bytes.

0
source

All Articles