pointer and array

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Leon Brodskiy

    pointer and array

    Hi,

    Could please anyone clarify about pointer and array in C?

    If I have:

    int arr[10];

    The following two commands will be the same: arr and &arr[0].

    What about &arr? Is it not the same thing?


  • Joona I Palaste

    #2
    Re: pointer and array

    Leon Brodskiy <ivan@rogers.co m> scribbled the following:[color=blue]
    > Hi,[/color]
    [color=blue]
    > Could please anyone clarify about pointer and array in C?[/color]
    [color=blue]
    > If I have:[/color]
    [color=blue]
    > int arr[10];[/color]
    [color=blue]
    > The following two commands will be the same: arr and &arr[0].[/color]

    They're expressions, not commands. But yes, they're the same thing,
    in a value context.
    [color=blue]
    > What about &arr? Is it not the same thing?[/color]

    Not the same thing at all. It's the address of the entire array, not
    its first element. The most practical meaning of this is that such
    addresses increment in terms of 10*sizeof(int), not in terms of
    sizeof(int).

    --
    /-- Joona Palaste (palaste@cc.hel sinki.fi) ------------- Finland --------\
    \-------------------------------------------------------- rules! --------/

    Comment

    • Leon Brodskiy

      #3
      Re: pointer and array

      Thanks for your answer.
      I'm asking because I have found in a program the following call:

      void f1(char inp[10])
      {...}

      void main()
      {...
      char str[10];
      ....
      f1(&str);
      ....
      }

      I tought this is a bug and this is not supposed to work but it does work.
      Function receives pointer to char. I send to the function a pointer to a
      pointer to char but still seems like in arrays it is the same pointer. So,
      is this case str and &str the same?

      Thanks.

      "Joona I Palaste" <palaste@cc.hel sinki.fi> wrote in message
      news:cq4f5i$jfm $1@oravannahka. helsinki.fi...[color=blue]
      > Leon Brodskiy <ivan@rogers.co m> scribbled the following:[color=green]
      > > Hi,[/color]
      >[color=green]
      > > Could please anyone clarify about pointer and array in C?[/color]
      >[color=green]
      > > If I have:[/color]
      >[color=green]
      > > int arr[10];[/color]
      >[color=green]
      > > The following two commands will be the same: arr and &arr[0].[/color]
      >
      > They're expressions, not commands. But yes, they're the same thing,
      > in a value context.
      >[color=green]
      > > What about &arr? Is it not the same thing?[/color]
      >
      > Not the same thing at all. It's the address of the entire array, not
      > its first element. The most practical meaning of this is that such
      > addresses increment in terms of 10*sizeof(int), not in terms of
      > sizeof(int).
      >
      > --
      > /-- Joona Palaste (palaste@cc.hel sinki.fi) ------------- Finland --------\
      > \-------------------------------------------------------- rules! --------/[/color]


      Comment

      • Joona I Palaste

        #4
        Re: pointer and array

        Leon Brodskiy <ivan@rogers.co m> scribbled the following:[color=blue]
        > Thanks for your answer.
        > I'm asking because I have found in a program the following call:[/color]
        [color=blue]
        > void f1(char inp[10])
        > {...}[/color]
        [color=blue]
        > void main()[/color]

        Change this to int main(void).
        [color=blue]
        > {...
        > char str[10];
        > ...
        > f1(&str);
        > ...
        > }[/color]
        [color=blue]
        > I tought this is a bug and this is not supposed to work but it does work.
        > Function receives pointer to char. I send to the function a pointer to a
        > pointer to char but still seems like in arrays it is the same pointer. So,
        > is this case str and &str the same?[/color]

        That program is *NOT* correct. You are supposed to call f1(str), not
        f1(&str). If the function f1 assigns its parameter to a char pointer
        (char*), it might work under your implementation. But trying to access
        the char array pointer (char(*)[]) as if it were a char pointer will
        yield wrong results, mainly for the reasons I stated.

        --
        /-- Joona Palaste (palaste@cc.hel sinki.fi) ------------- Finland --------\
        \-------------------------------------------------------- rules! --------/
        "Ice cream sales somehow cause drownings: both happen in summer."
        - Antti Voipio & Arto Wikla

        Comment

        • Joona I Palaste

          #5
          Re: pointer and array

          Joona I Palaste <palaste@cc.hel sinki.fi> scribbled the following:[color=blue]
          > Leon Brodskiy <ivan@rogers.co m> scribbled the following:[color=green]
          >> Thanks for your answer.
          >> I'm asking because I have found in a program the following call:[/color][/color]
          [color=blue][color=green]
          >> void f1(char inp[10])
          >> {...}[/color][/color]
          [color=blue][color=green]
          >> void main()[/color][/color]
          [color=blue]
          > Change this to int main(void).[/color]
          [color=blue][color=green]
          >> {...
          >> char str[10];
          >> ...
          >> f1(&str);
          >> ...
          >> }[/color][/color]
          [color=blue][color=green]
          >> I tought this is a bug and this is not supposed to work but it does work.
          >> Function receives pointer to char. I send to the function a pointer to a
          >> pointer to char but still seems like in arrays it is the same pointer. So,
          >> is this case str and &str the same?[/color][/color]
          [color=blue]
          > That program is *NOT* correct. You are supposed to call f1(str), not
          > f1(&str). If the function f1 assigns its parameter to a char pointer
          > (char*), it might work under your implementation. But trying to access
          > the char array pointer (char(*)[]) as if it were a char pointer will
          > yield wrong results, mainly for the reasons I stated.[/color]

          I should not be answering C questions late in the evening. That program
          is still wrong, but my answer above is wrong too. Any possible
          assignment from &str to a char pointer happens *before* f1's code
          begins, so what f1 does to the pointer does not matter. Does assigning
          a char array pointer to a char pointer cause undefined behaviour?

          --
          /-- Joona Palaste (palaste@cc.hel sinki.fi) ------------- Finland --------\
          \-------------------------------------------------------- rules! --------/
          "Remember: There are only three kinds of people - those who can count and those
          who can't."
          - Vampyra

          Comment

          • Leon Brodskiy

            #6
            Re: pointer and array

            If we leave char array pointer for a second, can we say that the program
            will always work correctly?

            Would it be correct to say that a difference between str and &str is that
            str is char* (points to one single character) and &str is a pointer to an
            array(points to array of 10 characters)? If this is a true then in the
            program should not be any difference if we use &str or str - both of them
            will send to the function the address of the first element in the array.

            Thanks in advance.

            "Joona I Palaste" <palaste@cc.hel sinki.fi> wrote in message
            news:cq4g9j$jrq $1@oravannahka. helsinki.fi...[color=blue]
            > Joona I Palaste <palaste@cc.hel sinki.fi> scribbled the following:[color=green]
            > > Leon Brodskiy <ivan@rogers.co m> scribbled the following:[color=darkred]
            > >> Thanks for your answer.
            > >> I'm asking because I have found in a program the following call:[/color][/color]
            >[color=green][color=darkred]
            > >> void f1(char inp[10])
            > >> {...}[/color][/color]
            >[color=green][color=darkred]
            > >> void main()[/color][/color]
            >[color=green]
            > > Change this to int main(void).[/color]
            >[color=green][color=darkred]
            > >> {...
            > >> char str[10];
            > >> ...
            > >> f1(&str);
            > >> ...
            > >> }[/color][/color]
            >[color=green][color=darkred]
            > >> I tought this is a bug and this is not supposed to work but it does[/color][/color][/color]
            work.[color=blue][color=green][color=darkred]
            > >> Function receives pointer to char. I send to the function a pointer to[/color][/color][/color]
            a[color=blue][color=green][color=darkred]
            > >> pointer to char but still seems like in arrays it is the same pointer.[/color][/color][/color]
            So,[color=blue][color=green][color=darkred]
            > >> is this case str and &str the same?[/color][/color]
            >[color=green]
            > > That program is *NOT* correct. You are supposed to call f1(str), not
            > > f1(&str). If the function f1 assigns its parameter to a char pointer
            > > (char*), it might work under your implementation. But trying to access
            > > the char array pointer (char(*)[]) as if it were a char pointer will
            > > yield wrong results, mainly for the reasons I stated.[/color]
            >
            > I should not be answering C questions late in the evening. That program
            > is still wrong, but my answer above is wrong too. Any possible
            > assignment from &str to a char pointer happens *before* f1's code
            > begins, so what f1 does to the pointer does not matter. Does assigning
            > a char array pointer to a char pointer cause undefined behaviour?
            >
            > --
            > /-- Joona Palaste (palaste@cc.hel sinki.fi) ------------- Finland --------\
            > \-------------------------------------------------------- rules! --------/
            > "Remember: There are only three kinds of people - those who can count and[/color]
            those[color=blue]
            > who can't."
            > - Vampyra[/color]


            Comment

            • Joona I Palaste

              #7
              Re: pointer and array

              Leon Brodskiy <ivan@rogers.co m> scribbled the following:[color=blue]
              > If we leave char array pointer for a second, can we say that the program
              > will always work correctly?[/color]

              No. The C standard allows for an implementation to behave erroneously
              when a pointer value is assigned to a variable of incompatible type.
              [color=blue]
              > Would it be correct to say that a difference between str and &str is that
              > str is char* (points to one single character) and &str is a pointer to an
              > array(points to array of 10 characters)?[/color]

              Yes.
              [color=blue]
              > If this is a true then in the
              > program should not be any difference if we use &str or str - both of them
              > will send to the function the address of the first element in the array.[/color]

              That is not true in the general case. At least I think it's not. Maybe
              some of the real C gurus here can answer my original question about
              whether it is undefined behaviour?

              --
              /-- Joona Palaste (palaste@cc.hel sinki.fi) ------------- Finland --------\
              \-------------------------------------------------------- rules! --------/
              "Parthenogeneti c procreation in humans will result in the founding of a new
              religion."
              - John Nordberg

              Comment

              • Keith Thompson

                #8
                Re: pointer and array

                "Leon Brodskiy" <ivan@rogers.co m> writes:[color=blue]
                > If we leave char array pointer for a second, can we say that the program
                > will always work correctly?
                >
                > Would it be correct to say that a difference between str and &str is that
                > str is char* (points to one single character) and &str is a pointer to an
                > array(points to array of 10 characters)? If this is a true then in the
                > program should not be any difference if we use &str or str - both of them
                > will send to the function the address of the first element in the array.[/color]

                Please don't top-post. Your response should follow any quoted text,
                not precede it.

                No we can't say that the program will always work correctly. A
                pointer-to-char and a pointer-to-array-of-char are two distinct types.
                On most systems, they happen to have the same representation and can
                be used more or less interchangeably , but the language standard
                doesn't guarantee this.

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                Comment

                • Joe Wright

                  #9
                  Re: pointer and array

                  Joona I Palaste wrote:[color=blue]
                  > Leon Brodskiy <ivan@rogers.co m> scribbled the following:
                  >[color=green]
                  >>If we leave char array pointer for a second, can we say that the program
                  >>will always work correctly?[/color]
                  >
                  >
                  > No. The C standard allows for an implementation to behave erroneously
                  > when a pointer value is assigned to a variable of incompatible type.
                  >
                  >[color=green]
                  >>Would it be correct to say that a difference between str and &str is that
                  >>str is char* (points to one single character) and &str is a pointer to an
                  >>array(point s to array of 10 characters)?[/color]
                  >
                  >
                  > Yes.
                  >
                  >[color=green]
                  >>If this is a true then in the
                  >>program should not be any difference if we use &str or str - both of them
                  >>will send to the function the address of the first element in the array.[/color]
                  >
                  >
                  > That is not true in the general case. At least I think it's not. Maybe
                  > some of the real C gurus here can answer my original question about
                  > whether it is undefined behaviour?
                  >[/color]

                  The two yield incompatible pointer types. I suppose a diagnostic is
                  required. I too await guru WRT undefined behavior.

                  --
                  Joe Wright mailto:joewwrig ht@comcast.net
                  "Everything should be made as simple as possible, but not simpler."
                  --- Albert Einstein ---

                  Comment

                  • infobahn

                    #10
                    Re: pointer and array

                    Leon Brodskiy wrote:[color=blue]
                    > Thanks for your answer.
                    > I'm asking because I have found in a program the following call:
                    >
                    > void f1(char inp[10])
                    > {...}
                    >
                    > void main()[/color]

                    A simple mistake. You meant:

                    int main(void)
                    [color=blue]
                    > {...
                    > char str[10];
                    > ....
                    > f1(&str);[/color]

                    This should be f1(str);

                    &str is a char (*)[10], not a char *, so it has the wrong type
                    for the f1() function.

                    Comment

                    • Barry Schwarz

                      #11
                      Re: pointer and array

                      On Sun, 19 Dec 2004 13:03:47 -0800, "Leon Brodskiy" <ivan@rogers.co m>
                      wrote:
                      [color=blue]
                      >Thanks for your answer.
                      >I'm asking because I have found in a program the following call:
                      >
                      >void f1(char inp[10])
                      >{...}
                      >
                      >void main()
                      >{...
                      >char str[10];
                      >...
                      >f1(&str);[/color]

                      This requires a diagnostic. &str has type pointer to array of 10
                      char. f1 requires an argument of type pointer to char. These two
                      types are not compatible (implicit conversion between them is not
                      allowed). You need to up the warning level of your compiler so that
                      the required diagnostic is not suppressed.
                      [color=blue]
                      >...
                      >}
                      >
                      >I tought this is a bug and this is not supposed to work but it does work.
                      >Function receives pointer to char. I send to the function a pointer to a
                      >pointer to char but still seems like in arrays it is the same pointer. So,
                      >is this case str and &str the same?[/color]

                      The expressions str and &str both evaluate to the same location in
                      memory but with different types. Apparently on your system, the two
                      types have the same representation so f1 is unaware you provided an
                      incorrect argument.

                      Passing an argument of the wrong type invokes undefined behavior. It
                      is your misfortune that this behavior takes the form of appearing to
                      work.




                      <<Remove the del for email>>

                      Comment

                      • CBFalconer

                        #12
                        Re: pointer and array

                        Leon Brodskiy wrote:[color=blue]
                        >
                        > If we leave char array pointer for a second, can we say that the
                        > program will always work correctly?[/color]
                        .... snip ...

                        Please do not toppost in c.l.c. Your answer belongs after (or
                        interspersed with) the snipped material quoted, which the snippage
                        removing anything not germane to your reply.

                        In technical newsgroups top-posting is consider gauche, ignorant,
                        and rude.

                        --
                        Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
                        Available for consulting/temporary embedded and systems.
                        <http://cbfalconer.home .att.net> USE worldnet address!


                        Comment

                        • Dave Vandervies

                          #13
                          Re: pointer and array

                          In article <gNGdnfsLuuZheF jcRVn-sQ@comcast.com> ,
                          Joe Wright <joewwright@com cast.net> wrote:[color=blue]
                          >Joona I Palaste wrote:[color=green]
                          >> Leon Brodskiy <ivan@rogers.co m> scribbled the following:[/color][/color]

                          [str is an array][color=blue][color=green][color=darkred]
                          >>>If this is a true then in the
                          >>>program should not be any difference if we use &str or str - both of them
                          >>>will send to the function the address of the first element in the array.[/color]
                          >>
                          >> That is not true in the general case. At least I think it's not. Maybe
                          >> some of the real C gurus here can answer my original question about
                          >> whether it is undefined behaviour?[/color]
                          >
                          >The two yield incompatible pointer types. I suppose a diagnostic is
                          >required. I too await guru WRT undefined behavior.[/color]

                          str has type "array of [I assume] char", which decays to "pointer to
                          char", pointing at the first char in the array.
                          &str has type "pointer to array of char", and points at (the beginning
                          of) the array; this happens to be the same memory location as the char
                          that the pointer that str decays to points at.

                          So, the types are different (and incompatible), but the values are
                          the same.

                          A diagnostic is required (because the types are incompatible). If the
                          compiler generates an executable anyways and if you ignore the diagnostic
                          and run the executable, you invoke undefined behavior.
                          If the two pointers have the same representation (a reasonable assumption
                          on a modern general-purpose processor like the one the OP is most likely
                          trying to run the code on), this particular undefined behavior is likely
                          to be "works as expected" (the compiler would have to go out of its way
                          to break it, since the values and the representations are the same).

                          A compiler for such an architecture invoked in "sorta-conforming
                          mode" could ignore the error. (Not issuing a diagnostic would make
                          it non-conforming, but that would probably be a Rather Small part of
                          its non-conformingness. ) This doesn't mean the code isn't broken,
                          just that it's the kind of bug that has very strong survival instincts.
                          It won't come out and bite you until you're absolutely certain that
                          there's nothing wrong with that particular chunk of code, so you'll
                          waste your time and energy looking somewhere else.


                          dave

                          --
                          Dave Vandervies dj3vande@csclub .uwaterloo.ca
                          I recently read a book on mathematical kooks, oddballs and cranks. There's a
                          mention in it of various societies dedicated to trying to get people to change
                          to base 12. One of them publishes its journal in Esperanto. --Joe Zeff, SDM

                          Comment

                          • Chris Torek

                            #14
                            Re: pointer and array

                            In article <cq4tnh$k9e$1@r umours.uwaterlo o.ca>
                            Dave Vandervies <dj3vande@csclu b.uwaterloo.ca> wrote:[color=blue]
                            >So, the types are different (and incompatible),[/color]

                            Definitely.
                            [color=blue]
                            >but the values are the same.[/color]

                            Well, yes; but also no. Because they have different types, it is
                            impossible to compare the values, at least not without help.

                            Consider a similar example, using "int" and "float" instead:

                            int i = 3;
                            float f = 3.14;

                            Are these equal? Let us find out:

                            % cat t.c
                            #include <stdio.h>

                            int equal(int a, int b) {
                            return a == b;
                            }

                            int main(void) {
                            int i = 3;
                            float f = 3.14;

                            if (equal(i, f))
                            printf("i and f are equal\n");
                            else
                            printf("i and f are not equal\n");
                            return 0;
                            }
                            % cc -o t -O -Wall -W -ansi -pedantic t.c
                            % ./t
                            i and f are equal
                            %

                            Well, there you go -- 3 is in fact the same value as 3.14.

                            Of course, this is complete nonsense; and if we change the equal()
                            function to take two "double" values, we find that 3 != 3.14.

                            So which is it? Is 3 equal to 3.14, or is 3 not equal to 3.14?
                            Ask anyone numerate and you will hear "they are not", but in C,
                            they are -- at least, sometimes. Before we can compare them,
                            we have to convert them to a common type, and the conversion
                            process can change the values. Converting a "float" 3.14 to an
                            "int" truncates it to 3, so 3 == 3; converting both to double
                            expands 3 to 3.0, and leaves 3.14 as something close to 3.14
                            (it becomes about 3.140000104904, on a typical machine today).

                            Note that this last item -- the fact that 3.14 is not exact, and
                            as a double, actually has some digits after four more zeros --
                            means that sometimes, even 3.14 is not equal to 3.14 (depending
                            on just what is behind those zeros):

                            % cat u.c
                            #include <stdio.h>

                            int equal(double a, double b) {
                            return a == b;
                            }

                            int main(void) {
                            float f = 3.14;

                            if (equal(f, 3.14))
                            printf("f is equal to 3.14\n");
                            else
                            printf("f is not equal to 3.14\n");
                            return 0;
                            }
                            % cc -o u -O -Wall -W -ansi -pedantic u.c
                            % ./u
                            f is not equal to 3.14
                            %

                            Clearly, we have to be careful with conversions -- they make
                            things that are obvious (like 3.14 == 3.14) turn out to be false,
                            sometimes.

                            The same holds for pointers. Given two differently-typed pointers,
                            we have to convert at least one of them, if not both, before we
                            can even compare them. If we have:

                            T1 *p1;
                            T2 *p2;

                            where T1 and T2 are different types, and we assign values to p1
                            and p2, and then convert them:

                            if (p1 == (T1 *)p2)

                            and this claims they are equal -- well, what if this is like the
                            int 3 and the float 3.14, that are equal when we convert them both
                            to int?

                            In some sense, this whole thing is not even an interesting question.
                            If the types differ, we should not be comparing the things in the
                            first place. But sometimes we want to do it anyway. In that case,
                            how do we convert them without screwing up the result?

                            The int-and-float case continues to be instructive. If we rewrite
                            equal() to take two "float"s, 3 != 3.14, and we do not have to
                            worry about 3.14 != 3.14. So this looks like a good idea. But
                            hang on: what happens if we compare (int)33554432 with (double)3355443 3.0?

                            I am not going to quote the C code here, but the trick is, I have
                            chosen an int that is too big for a "float" on my machine, so that
                            the "double" 33554433.0 becomes 33554432.0 after conversion to
                            float. This makes the numbers equal, when obviously they are not.
                            It turns out that "float" is *not* good enough as a common type,
                            for comparing int-and-double. The reason is that, while float
                            obviously preserves all float values, conversion to float irrecoverably
                            alters certain int values. Similarly, int is not good for comparing
                            either int-and-double or int-and-float, because conversion to int
                            alters many float or double values.

                            What we really need is a common type that *always* produces a
                            recoverable transformation. That is, given two values v1 and v2
                            of types T1 and T2 respectively, we need a type T3 where:

                            (T1)(T3)v1 == v1 /* i.e., (T3)v1 is recoverable */

                            and:

                            (T2)(T3)v2 == v2 /* (T3)v2 is also recoverable */

                            Given such a type, we can finally come up with a usable definition
                            of "is equal to": v1 is equal to v2 if (T3)v1 == (T3)v2. This
                            definition is (I claim) also consistent if, for every additional
                            type T4 for which the "recoverabl e transformation" property holds,
                            the "is equal to" relationship remains unchanged when using type
                            T4.

                            For data pointers in C, there is definitely such a type T3: the
                            "void *" type (which must use the same underlying representation
                            as "char *", which has consequences that are beyond the scope of
                            this newsgroup posting :-) ) allows you to convert any valid value
                            from some other data-pointer type, to "void *", then back, and
                            always get a result that compares equal to the original pointer.

                            Is there a type T4 (other than "char *" with its same-representation
                            thing)? This is implementation-dependent. So we can define an
                            "is equal to" relationship using "void *", but we cannot say for
                            certain whether it is consistent.

                            Note that, as Dave Vandervies already said, this "is equal to"
                            definition does *not* mean "is compatible with": on some machines,
                            passing a "char *" where an "int *" is required (or vice versa)
                            will not work properly, even if the two pointer values are "equal"
                            under void-star conversions. In this particular case, I am not
                            even sure you can prove that &arr and &arr[0] are "void-star-equal".
                            (I think they *are* void-star-equal; I just have trouble proving
                            it!)
                            --
                            In-Real-Life: Chris Torek, Wind River Systems
                            Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
                            email: forget about it http://web.torek.net/torek/index.html
                            Reading email is like searching for food in the garbage, thanks to spammers.

                            Comment

                            • E. Robert Tisdale

                              #15
                              Re: pointer and array

                              Leon Brodskiy wrote:
                              [color=blue]
                              > Could please anyone clarify about pointer and array in C?
                              >
                              > If I have:
                              >
                              > int arr[10];
                              >
                              > The following two commands will be the same: arr and &arr[0].
                              >
                              > What about &arr? Is it not the same thing?[/color]
                              [color=blue]
                              > cat main.c[/color]
                              #include <stdio.h>

                              int main(int argc, char* argv[]) {
                              int arr[10];
                              fprintf(stdout, "sizeof(arr ) = %u\n", sizeof(arr));
                              fprintf(stdout, "sizeof(&ar r[0]) = %u\n", sizeof(&arr[0]));
                              return 0;
                              }
                              [color=blue]
                              > gcc -Wall -std=c99 -pedantic -o main main.c
                              > ./main[/color]
                              sizeof(arr) = 40
                              sizeof(&arr[0]) = 4

                              arr is the name of an array of 10 objects of type int.
                              &arr[0] is a pointer to the first object in that array.

                              Comment

                              Working...