2
votes
#include<stdio.h> 
int main()
{
    int i=10,j=20,diff;
    diff=&j-&i;
    printf("\nAddress of i=%u Address of j=%u",&i,&j);
    printf("\nDifference of address i and j is %d\n",diff);
    return 0;
}

The output I got is:

Address of i=3012788 Address of j=3012776
Difference of address i and j is -3

But the difference between the addresses here is 2.

When I do diff=&i-&j, I get the following output:

Address of i=2751740 Address of j=2751728
Difference of address i and j is 3

But the difference here between the addresses is 12.

When two integer variables are declared, its not necessary for the second variable to occupy the next four bytes of the address occupied by the first variable. But why the differences are not actually what it has to be?

5
Ignoring the fact that your ptr difference is undefined, in general if you want to do ptr difference you should use ptrdiff_txanatos
At this point, if you truly want to know what happened (why the compiler changed the ordering of the ints and inserted some space) you should write what OS you are using (and if 32 or 64 bits), what compiler you used (and which version) and what parameters you passed to it. Then perhaps someone will be able to tell you why THAT compiler on THAT platform does THAT things.xanatos
i'm using windows 7 - 32 bit OS and visual studio2008 for compiling the c programs.Angus
Found. The Visual C++ in Debug mode adds some stack guards around your variables, so that you don't corrupt them with "wrong" pointer arithmetic. He then reorders the variables, so in memory they are: diff, (8 byte space), j, (8 byte space), i. Try adding this code before the end of the program: *(&j + 1) = 0; and launch it: the debugger will signal a stack corruption around the variable j.xanatos
@xanatos:I did as you tod me to do and it thrown an error message that the stack around the variable j is corrupted.&j+1 = address of j+size of int. so it will move to the next 4 bytes. whichh corrupts the address of i too.Please correct me if my assumption about this is wrong.Angus

5 Answers

8
votes

First of all, it's not legal to do arithmetic on addresses that are not from the same block of memory (array etc).

You second question is more interesting. You are subtracting two addresses and it defies arithmetic. Here is what is happening.

This is how pointer arithmetic works:

  • pointer + x actually means pointer + sizeof *pointer
  • pointer1 - pointer2 actually means (pointer1 - pointer2) / sizeof *either

So you expect 12 and you get 3 = 12 / 4. That's because an int on your platform is 4 bytes long.

3
votes

Computing the difference between pointers that do not point into the same array (as in your case) is undefined behavior in C. See this for more information and references.

3
votes

Did you try:

    diff=(int)&j-(int)&i;
2
votes

When an 2 integer variables are declared its not necessary for the second variable to occupy the next four bytes of the address occupied by the first variable?

NO, The address can be anywhere, the compiler chosses, unless ofcourse you have an array.

1
votes

You are using pointer arithmetic. Because int is 4 bytes on your machine, result * 4 is the distance between the two address. However you can apply conversion like (int) on the pointers to get what you expected.