9

Why is the difference between the two addresses wrong? http://codepad.org/NGDqFWjJ

#include<stdio.h>
int main()
{
   int i = 10, j = 20;
   int *p = &i;
   int *q = &j;
   int c = p - q;
   printf("%d\n", p);
   printf("%d\n", q);
   printf("%d", c);
   return 0;
}

Output:

-1083846364
-1083846368
1
Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
Ava
  • 5,783
  • 27
  • 58
  • 86

3 Answers3

24

First, pointer arithmetic isn't defined when performed on unrelated pointers.

Second, it makes sense. When subtracting pointers you get the number of elements between those addresses, not the number of bytes.

If you were to try that with

char *p1 = &i, *p2 = &j;

you would get a different result.


As a side note, use %p when printing pointers.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • Strictly speaking that's true, but every implementation I've ever used does "the right thing". So does the OP's, actually. – Carl Norum Mar 24 '12 at 20:49
  • Can you please confirm that this holds true also for C++, according to the standard. (I *know* it is true, but I'd like to see that stated in writing, if possible. Thanks!) – Dan Nissenbaum Jun 17 '14 at 15:55
14

As others have said, the result you get is in a multiple of the size of the type the pointers are pointing to. Cast them to be char pointers and the result you get will be in terms of bytes. Also, you should use the ptrdiff_t type, so that on systems with 64-bit pointers the type should be large enough to hold the result.

ptrdiff_t c = (char*)p - (char*)q;

Also note that taking the difference of the addresses of two values that aren't in the same array is undefined in the standard, but does work on about every system.

Macil
  • 3,575
  • 1
  • 20
  • 18
  • I get an error for `arithmetic on pointers to void` when I attempt this. – Yu Chen Nov 05 '17 at 21:45
  • 1
    Turns out that arithmetic on `void*` pointers is [nonstandard behavior](https://stackoverflow.com/a/3524270/1289657) only supported by some compilers with(out) certain flags. I've changed the answer to only recommend `char*` pointers instead, which works correctly and is standard behavior. – Macil Nov 06 '17 at 22:45
2

Strictly speaking, your program causes a few kinds of undefined behaviour, first due to the pointer arithmetic on unrelated pointers, and then by having mismatched format strings and arguments in your print statements. However, even if those were corrected, you'd see the same results. The reason the difference is 1 is because pointer arithmetic gives results in units of the size of the pointed to type - in your case int is a 4-byte type, so subtracting int * pointers that point 4 bytes apart yields a result of 1.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469