Calculating the address of the element past the end of the array

Discussion in 'C Programming' started by raphael.maggi@gmail.com, May 11, 2009.

  1. Guest

    Is this a valid way of calculating the address of the element past the
    end of an array?

    int main() {
    int array[10];
    int *ptr = &array[10];

    return 0;
    }

    is it acessing the element or just calculating its address, or both?
    , May 11, 2009
    #1
    1. Advertising

  2. writes:

    > Is this a valid way of calculating the address of the element past the
    > end of an array?
    >
    > int main() {
    > int array[10];
    > int *ptr = &array[10];
    >
    > return 0;
    > }


    Yes.

    > is it acessing the element or just calculating its address, or both?


    All it does is calculate the address.

    --
    Ben.
    Ben Bacarisse, May 11, 2009
    #2
    1. Advertising

  3. On 11 May, 17:31, wrote:
    > Is this a valid way of calculating the address of the element past the
    > end of an array?
    >
    > int main() {
    > int array[10];
    > int *ptr = &array[10];
    >
    > return 0;
    >
    > }
    >
    > is it acessing the element or just calculating its address, or both?


    There is no element to access because you are passed the end of
    the array. Even if you had initialised the array there would
    still not be an element to access. So it only calculates the
    address. You can achieve the same thing more simply by writing
    ptr = array + 10;

    --
    Who's your mama?
    Spiros Bousbouras, May 11, 2009
    #3
  4. Pietro Cerutti <> writes:

    > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:
    >
    >> Is this a valid way of calculating the address of the element past the
    >> end of an array?
    >>
    >> int main() {
    >> int array[10];
    >> int *ptr = &array[10];
    >>
    >> return 0;
    >> }
    >>
    >> is it acessing the element or just calculating its address, or both?

    >
    > It is both accessing the element and then getting the address of it.


    <panto audience>
    Oh, no it isn't!
    </panto audience>

    Short-hand reasoning is: array[0] is *(array + 10) so the RHS is
    &*(array + 10). & and * cancel out in such an expression. The result
    is that no access is implied or done.

    (The wording in the standard explicitly covers the [] case but I think
    it is simpler to remember the general rule.)

    --
    Ben.
    Ben Bacarisse, May 11, 2009
    #4
  5. On May 11, 2:16 pm, Ben Bacarisse <> wrote:
    > Pietro Cerutti <> writes:
    > > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:

    >
    > >> Is this a valid way of calculating the address of the element past the
    > >> end of an array?

    >
    > >> int main() {
    > >>     int array[10];
    > >>     int *ptr = &array[10];

    >
    > >>     return 0;
    > >> }

    >
    > >> is it acessing the element or just calculating its address, or both?

    >
    > > It is both accessing the element and then getting the address of it.

    >
    > <panto audience>
    > Oh, no it isn't!
    > </panto audience>
    >
    > Short-hand reasoning is: array[0] is *(array + 10) so the RHS is
    > &*(array + 10).  & and * cancel out in such an expression.  The result
    > is that no access is implied or done.


    why they cancel out?
    shouldn't the dereference occurs first and then the reference?
    Raphael Maggi, May 11, 2009
    #5
  6. jameskuyper Guest

    Pietro Cerutti wrote:
    > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:
    >
    > > Is this a valid way of calculating the address of the element past the
    > > end of an array?
    > >
    > > int main() {
    > > int array[10];
    > > int *ptr = &array[10];
    > >
    > > return 0;
    > > }
    > >
    > > is it acessing the element or just calculating its address, or both?

    >
    > It is both accessing the element and then getting the address of it.


    6.5.3.2p3: "if the operand is the result of a [] operator, neither the
    & operator nor the unary * that is implied by the [] is evaluated and
    the result is as if the & operator were removed and the [] operator
    were changed to a + operator."

    In other words: &array[10], &*(array+10), and array+10 all mean
    exactly the same thing. None of them actually accesses the (non-
    existent) element.

    > Try instead with this:
    >
    > size_t address = (size_t) &array + sizeof(array) * sizeof(*array)


    * I think you're assuming that sizeof(array) gives the number of
    elements in the array, and that sizeof(*array) gives the number of
    bytes in each element, so that multiplying them will give you the
    total size of the array in bytes. That's incorrect: sizeof(array)
    gives you the size of the array in bytes; no multiplication is
    required.

    * You're assuming that size_t is big enough to hold an address; that's
    not guaranteed - that's what intptr_t and uintptr_t are for. I'll
    assume that you meant to replace size_t with intptr_t.

    * You're assuming that the result of converting a pointer to intptr_t
    is the address. The result of such a conversion is implementation-
    defined. A footnote says "The mapping functions for converting a
    pointer to an integer or an integer to a pointer are intended to be
    consistent with the addressing structure of the execution
    environment.", however, footnotes are not normative, and even if it
    were, "consistent with the addressing structure" doesn't have to mean
    that it's the actual address. In particular, it's not necessarily the
    case that adding the sizeof of the array to that address will be
    meaningful. The number could, for instance, have a segment number in
    the low-order bytes, and an offset within the segment in the high-
    order bytes, in which case such an addition would produce a thoroughly
    meaningless result.
    jameskuyper, May 11, 2009
    #6
  7. On May 11, 2:46 pm, jameskuyper <> wrote:
    > Pietro Cerutti wrote:
    > > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:

    >
    > > > Is this a valid way of calculating the address of the element past the
    > > > end of an array?

    >
    > > > int main() {
    > > >     int array[10];
    > > >     int *ptr = &array[10];

    >
    > > >     return 0;
    > > > }

    >
    > > > is it acessing the element or just calculating its address, or both?

    >
    > > It is both accessing the element and then getting the address of it.

    >
    > 6.5.3.2p3: "if the operand is the result of a [] operator, neither the
    > & operator nor the unary * that is implied by the [] is evaluated and
    > the result is as if the & operator were removed and the [] operator
    > were changed to a + operator."
    >
    > In other words: &array[10], &*(array+10), and array+10 all mean
    > exactly the same thing. None of them actually accesses the (non-
    > existent) element.


    I think this clarified my question

    thank you all
    Raphael Maggi, May 11, 2009
    #7
  8. Raphael Maggi <> writes:

    > On May 11, 2:16 pm, Ben Bacarisse <> wrote:
    >> Pietro Cerutti <> writes:
    >> > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:

    >>
    >> >> Is this a valid way of calculating the address of the element past the
    >> >> end of an array?

    >>
    >> >> int main() {
    >> >>     int array[10];
    >> >>     int *ptr = &array[10];

    >>
    >> >>     return 0;
    >> >> }

    >>
    >> >> is it acessing the element or just calculating its address, or both?

    >>
    >> > It is both accessing the element and then getting the address of it.

    >>
    >> <panto audience>
    >> Oh, no it isn't!
    >> </panto audience>
    >>
    >> Short-hand reasoning is: array[0] is *(array + 10) so the RHS is
    >> &*(array + 10).  & and * cancel out in such an expression.  The result
    >> is that no access is implied or done.

    >
    > why they cancel out?
    > shouldn't the dereference occurs first and then the reference?


    They cancel out because the language standard says they do. See
    6.5.3.2 paragraph 3:

    3 [...] If the operand is the result of a unary * operator, neither
    that operator nor the & operator is evaluated and the result is as
    if both were omitted, except that the constraints on the operators
    still apply and the result is not an lvalue. Similarly, if the
    operand is the result of a [] operator, neither the & operator nor
    the unary * that is implied by the [] is evaluated and the result
    is as if the & operator were removed and the [] operator were
    changed to a + operator. [...]

    --
    Ben.
    Ben Bacarisse, May 11, 2009
    #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. Replies:
    5
    Views:
    448
    Ben Bacarisse
    Dec 6, 2006
  2. Ioannis Vranos

    Pointing one past the end element

    Ioannis Vranos, Jan 6, 2008, in forum: C++
    Replies:
    17
    Views:
    502
    James Kanze
    Jan 8, 2008
  3. candide
    Replies:
    65
    Views:
    1,375
  4. Johannes Schaub (litb)

    Advancing past the last element of an array

    Johannes Schaub (litb), Dec 27, 2009, in forum: C Programming
    Replies:
    10
    Views:
    607
    Tim Rentsch
    Jan 13, 2010
  5. Peter
    Replies:
    9
    Views:
    136
Loading...

Share This Page