pointer arithmetic

B

barikat

int a[5];
int *Ptr1, *Ptr2;

Ptr1 = a;
Ptr1++;
Ptr2 = a;

printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);

Ptr1 = Ptr1 - Ptr2;

---------------------
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

Ptr1 : 00000001
Ptr2 : 0012FF68
----------------------

i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
a[1] - a[0] should be a[1] so 0012FF6C
probably i am wrong but i wanted to ask :)
 
W

Walter Roberson

int a[5];
int *Ptr1, *Ptr2;
Ptr1 = a;
Ptr1++;
Ptr2 = a;
printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);
Ptr1 = Ptr1 - Ptr2;

Ptr1 - Ptr2 is an arithmetic value which is the difference in offsets
in units of the type pointed to.
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

So the raw addresses are as above in your case, and the address
difference is sizeof(int), and to calculate the offset difference
you have to take the raw address difference and divide it by the
sizeof(int), so the pointer difference will turn out to be 4/4 = 1.

But then you take that arithmetic value 1, and you assign it into
a pointer, which is going to lead to implementation-defined behaviour.
Ptr1 : 00000001
Ptr2 : 0012FF68
i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,

Right, *pointer* arithmetic, not *address* arithmetic.
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]

Ptr1 is not a[1], Ptr1 is &a[1] which is (&a + 1) in pointer arithmetic,
which is (unsigned char *)&a + 1 * sizeof(int) in address arithmetic.
Similarily, Ptr2 is not a[0], Ptr2 is &a[0], which is (&a + 0) in
pointer arithmetic, which is (unsigned char *)&a + 0 * sizeof(int)
in address arithmetic.
a[1] - a[0] should be a[1] so 0012FF6C

a[1] - a[0] would be the -contents- of a[1] (an uninitialized integer)
minus the -contents- of a[0] (another uninitilized integer).

&a[1] - &a[0] would be (&a + 1) - (&a + 0) in pointer arithemetic,
which simplifies to 1 in pointer arithmetic. In address arithmetic,
it would come out as 4 (sizeof int) on your particular machine.
 
S

swengineer001

int a[5];
int *Ptr1, *Ptr2;

Ptr1 = a;
Ptr1++;
Ptr2 = a;

printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);

Ptr1 = Ptr1 - Ptr2;

---------------------
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

Ptr1 : 00000001
Ptr2 : 0012FF68
----------------------

i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
a[1] - a[0] should be a[1] so 0012FF6C
probably i am wrong but i wanted to ask :)

First of all a[1] - a[0] is not the same thing as Ptr1 - Ptr2. a[1] and
a[0] refer to the values of the int's stored in the first and second
elements of the array a. Ptr1 and Ptr2 are pointers to the locations of
the first and second elemts of the array a. If what you wanted was the
same thig as a[1] - a[0] you need *Ptr1 - *Ptr2.

Secondly the subtraction of one pointer from another is not going to
give you a pointer to the location that the first pointer is pointing
to, which is what you seem to be saying you were expecting although I
am not sure.
 
N

Neil Ferguson

int a[5];
int *Ptr1, *Ptr2;

Ptr1 = a;
Ptr1++;
Ptr2 = a;

printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);

Ptr1 = Ptr1 - Ptr2;

---------------------
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

Ptr1 : 00000001
Ptr2 : 0012FF68
----------------------

i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
a[1] - a[0] should be a[1] so 0012FF6C
probably i am wrong but i wanted to ask :)
If you live at 301 Elm Street and your friend lives at 303 Elm Street and
houses on your side of the street are odd-numbered, how many houses away
from you does your friend live?

N
 
K

Keith Thompson

int a[5];
int *Ptr1, *Ptr2;

Ptr1 = a;
Ptr1++;
Ptr2 = a;

printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);

Ptr1 = Ptr1 - Ptr2;

---------------------
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

Ptr1 : 00000001
Ptr2 : 0012FF68
----------------------

i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
a[1] - a[0] should be a[1] so 0012FF6C
probably i am wrong but i wanted to ask :)

Compile with warnings enabled.

The "%p" format expects an argument of type void*, which is not
compatible with int*. It may happen to work if void* and int* happen
to have the same representation (which they very commonly do), but you
can avoid any possible problems by converting the argument:

printf("Ptr1 : %p\n", (void*)Ptr1);
printf("Ptr2 : %p\n\n", (void*)Ptr2));

This is one of the few cases where a cast is actually appropriate.

Subtracting one pointer from another yields a result of the integer
type ptrdif_t. (This is valid only if both pointers point to elements
of the same array, which is the case here; otherwise it invokes
undefined behavior.) So you're trying to assign an integer value to a
pointer variable. The language allows you to convert an integer value
to a pointer type (the result is implementation-defined and very
likely not useful), but you can only do so with a cast; there is no
implicit conversion from integers to pointers (other than the special
case of a null pointer constant). So your assignment is a constraint
violation, and the compiler is required to issue a diagnostic message.
(If yours did so, you didn't bother to tell us.) The diagnostic can
be just a warning (if the compiler supports this implicit conversion
as an extension), but it's required for any conforming compiler. You
might have to pass some additional options to your compiler, for
example enabling certain warnings, to make it conforming.

Also, you posted only a code fragment; in particular, you didn't show
us all the code that produces the output you showed us. Next time, if
at all possible, please post a small, complete, self-contained,
compilable program. The fragment you posted happened to be clear
enough, but you can never be sure of that; quite often the seemingly
irrelevant piece of code that someone thinks isn't worth posting is
just the thing that causes or explains the problem.
 
M

milhous.30

Neil said:
int a[5];
int *Ptr1, *Ptr2;

Ptr1 = a;
Ptr1++;
Ptr2 = a;

printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);

Ptr1 = Ptr1 - Ptr2;

---------------------
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

Ptr1 : 00000001
Ptr2 : 0012FF68
----------------------

i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
a[1] - a[0] should be a[1] so 0012FF6C
probably i am wrong but i wanted to ask :)
If you live at 301 Elm Street and your friend lives at 303 Elm Street and
houses on your side of the street are odd-numbered, how many houses away
from you does your friend live?

N
Depends on the direction you go :)
 
S

swengineer001

Neil said:
int a[5];
int *Ptr1, *Ptr2;

Ptr1 = a;
Ptr1++;
Ptr2 = a;

printf("Ptr1 : %p\n", Ptr1);
printf("Ptr2 : %p\n\n", Ptr2);

Ptr1 = Ptr1 - Ptr2;

---------------------
Ptr1 : 0012FF6C
Ptr2 : 0012FF68

Ptr1 : 00000001
Ptr2 : 0012FF68
----------------------

i couldnt understand, Ptr1 = Ptr1 - Ptr2; line is a pointer arithmetic,
and Ptr1 should be 0012FF6C, because Ptr1 is a[1] and Ptr2 is a[0]
a[1] - a[0] should be a[1] so 0012FF6C
probably i am wrong but i wanted to ask :)
If you live at 301 Elm Street and your friend lives at 303 Elm Street and
houses on your side of the street are odd-numbered, how many houses away
from you does your friend live?

N
Depends on the direction you go :)

Not really, you both always live at the same location relative to each
other. But you are right that you can take the long way to get there
but that does not make your houses any farther apart.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top