pointer arithmetic

Discussion in 'C Programming' started by barikat@gmail.com, Jun 23, 2006.

  1. Guest

    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 :)
    , Jun 23, 2006
    #1
    1. Advertising

  2. wrote:
    > a[1] - a[0] should be a[1] so 0012FF6C
    > probably i am wrong but i wanted to ask :)


    Yes, that's wrong.
    Joshua Shinavier, Jun 23, 2006
    #2
    1. Advertising

  3. In article <>,
    <> wrote:
    > 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.
    --
    Prototypes are supertypes of their clones. -- maplesoft
    Walter Roberson, Jun 23, 2006
    #3
  4. Guest

    wrote:
    > 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.
    , Jun 23, 2006
    #4
  5. <> wrote in message
    news:...
    > 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
    Neil Ferguson, Jun 23, 2006
    #5
  6. writes:
    > 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.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Jun 23, 2006
    #6
  7. Guest

    Neil Ferguson wrote:
    > <> wrote in message
    > news:...
    > > 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 :)
    , Jul 1, 2006
    #7
  8. Guest

    wrote:
    > Neil Ferguson wrote:
    > > <> wrote in message
    > > news:...
    > > > 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.
    , Jul 1, 2006
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. a

    pointer arithmetic

    a, Sep 11, 2003, in forum: C++
    Replies:
    6
    Views:
    521
  2. Marc Schellens

    Iterator/pointer arithmetic

    Marc Schellens, Dec 5, 2003, in forum: C++
    Replies:
    15
    Views:
    845
    tom_usenet
    Dec 8, 2003
  3. dan

    Pointer arithmetic

    dan, Jan 6, 2004, in forum: C++
    Replies:
    1
    Views:
    361
    Jeff Schwab
    Jan 6, 2004
  4. ceo
    Replies:
    8
    Views:
    356
    Pete Becker
    Mar 10, 2005
  5. joshc
    Replies:
    5
    Views:
    556
    Keith Thompson
    Mar 31, 2005
Loading...

Share This Page