How to get array size from a pointer?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • ggnguser@gmail.com

    #1

    How to get array size from a pointer?

    It's part of a test and I'm stumped. There is a function

    void foo(char **x)

    The function signature is given and cannot be changed, so no passing
    of other values. The test case involves defining this variable:

    char *y[] = { /* bunch of stuff */ }

    and calling

    foo(y)

    In the above, "bunch of stuff" is a series of triplets, two strings
    followed by a null string (""). However, the last triplet ends with an
    integer 0. This seems that it's supposed to signify the end of the
    array. However, it appears to me that 0 is the same binary value as
    for the empty string (NUL, \0, whatever). So in effect, one cannot
    test for it as a sentry value because it's actually the same as the
    preceding triplets.

    How then, can the function foo() determine the bounds of the array?
    Knowing the bounds of the particular test case is not sufficient since
    the actual test suite may have arrays of varying size.
  • Bartc

    #2
    Re: How to get array size from a pointer?


    <ggnguser@gmail .comwrote in message
    news:3798e9c5-5247-40bc-a52c-d30c73cdcdc9@o4 0g2000prn.googl egroups.com...
    It's part of a test and I'm stumped. There is a function
    >
    void foo(char **x)
    >
    The function signature is given and cannot be changed, so no passing
    of other values. The test case involves defining this variable:
    >
    char *y[] = { /* bunch of stuff */ }
    >
    and calling
    >
    foo(y)
    >
    In the above, "bunch of stuff" is a series of triplets, two strings
    followed by a null string (""). However, the last triplet ends with an
    integer 0. This seems that it's supposed to signify the end of the
    array. However, it appears to me that 0 is the same binary value as
    for the empty string (NUL, \0, whatever). So in effect, one cannot
    test for it as a sentry value because it's actually the same as the
    preceding triplets.
    Any empty string is not necessarily NULL.

    { "ABC","","GHI", 0}

    Three non-NULL strings followed by a NULL.

    (vippstar will say NULL is not the same as 0. Whatever; if all you have to
    mark the end is 0, then use it and hope that on your system 0 will never be
    a legal string pointer.)

    --
    bartc

    Comment

    • vippstar@gmail.com

      #3
      Re: How to get array size from a pointer?

      On Oct 8, 4:11 pm, "ggngu...@gmail .com" <ggngu...@gmail .comwrote:
      It's part of a test and I'm stumped. There is a function
      >
      void foo(char **x)
      >
      The function signature is given and cannot be changed, so no passing
      of other values. The test case involves defining this variable:
      >
      char *y[] = { /* bunch of stuff */ }
      >
      and calling
      >
      foo(y)
      >
      In the above, "bunch of stuff" is a series of triplets, two strings
      followed by a null string (""). However, the last triplet ends with an
      integer 0. This seems that it's supposed to signify the end of the
      array. However, it appears to me that 0 is the same binary value as
      for the empty string (NUL, \0, whatever). So in effect, one cannot
      test for it as a sentry value because it's actually the same as the
      preceding triplets.
      char *y[] is an array of char * pointers. When a constant integer
      expression with the value 0 appears in integer context, it becomes a
      null pointer constant.
      It's the same if you had written 0 or NULL.
      How then, can the function foo() determine the bounds of the array?
      Knowing the bounds of the particular test case is not sufficient since
      the actual test suite may have arrays of varying size.
      Like strlen(); Strlen iterates until it encounters a byte whose value
      is 0; Your function would iterate until it encounters a pointer whose
      value is NULL.

      Comment

      • vippstar@gmail.com

        #4
        Re: How to get array size from a pointer?

        On Oct 8, 4:22 pm, "Bartc" <b...@freeuk.co mwrote:
        <ggngu...@gmail .comwrote in message
        >
        news:3798e9c5-5247-40bc-a52c-d30c73cdcdc9@o4 0g2000prn.googl egroups.com...
        >
        >
        >
        It's part of a test and I'm stumped. There is a function
        >
        void foo(char **x)
        >
        The function signature is given and cannot be changed, so no passing
        of other values. The test case involves defining this variable:
        >
        char *y[] = { /* bunch of stuff */ }
        >
        and calling
        >
        foo(y)
        >
        In the above, "bunch of stuff" is a series of triplets, two strings
        followed by a null string (""). However, the last triplet ends with an
        integer 0. This seems that it's supposed to signify the end of the
        array. However, it appears to me that 0 is the same binary value as
        for the empty string (NUL, \0, whatever). So in effect, one cannot
        test for it as a sentry value because it's actually the same as the
        preceding triplets.
        >
        Any empty string is not necessarily NULL.
        An empty string is _never_ NULL.
        { "ABC","","GHI", 0}
        >
        Three non-NULL strings followed by a NULL.
        What is a non-NULL string? A string can't be NULL! That doesn't make
        sense.
        (vippstar will say NULL is not the same as 0. Whatever; if all you have to
        mark the end is 0, then use it and hope that on your system 0 will never be
        a legal string pointer.)
        Bollocks. Don't put words in my mouth ever again.
        0 can never be a "legal string pointer".
        NULL is guaranteed to compare unequal to all addresses of objects.

        Comment

        • Ben Bacarisse

          #5
          Re: How to get array size from a pointer?

          "ggnguser@gmail .com" <ggnguser@gmail .comwrites:
          It's part of a test and I'm stumped. There is a function
          >
          void foo(char **x)
          >
          The function signature is given and cannot be changed, so no passing
          of other values. The test case involves defining this variable:
          >
          char *y[] = { /* bunch of stuff */ }
          >
          and calling
          >
          foo(y)
          >
          In the above, "bunch of stuff" is a series of triplets, two strings
          followed by a null string (""). However, the last triplet ends with an
          integer 0. This seems that it's supposed to signify the end of the
          array. However, it appears to me that 0 is the same binary value as
          for the empty string (NUL, \0, whatever). So in effect, one cannot
          test for it as a sentry value because it's actually the same as the
          preceding triplets.
          A little terminology: I'd call it a sentinel and I'd call "" an empty
          string (I see you do to). "Null string" is just too confusing a term
          to use safely.

          Your question: when you write a string literal ("a", "hello", even "")
          as an initialiser for a char * object, the characters in the string
          are put into to an array somewhere (you don't need to care where) and
          a pointer to that array is used as the value of the object. The array
          is null-terminated: a byte with value zero is placed at the end.
          Thus:

          char *empty = "";

          makes empty point to an array somewhere. That array need only contain
          one character: a zero byte (sometimes called a null character).

          C also permits any pointer to be set to a special value to show that
          the pointer does not point to an object. This is a null pointer and
          it quite different to a pointer that points to an array that happens
          to start with a null character. Thus:

          char *nowhere = 0;

          makes nowhere a null pointer. You can also use the macro NULL if you
          have included (one of) the right headers -- stddef.h for example.

          Give a char pointer p, you can tell if it is a null pointer by asking:

          if (p == 0) /* or p == NULL if you prefer */

          In fact, simply writing

          if (!p)

          is enough but to tell if p points to an empty string, you must ask

          if (*p == 0) /* or *p == '\0' if you prefer */

          The same test can also be written p[0] == 0, !p[0] or simply !*p.
          How then, can the function foo() determine the bounds of the array?
          Knowing the bounds of the particular test case is not sufficient since
          the actual test suite may have arrays of varying size.
          In short, it can't, but it can tell the difference between a null
          pointer and a non-null pointer that points at a null character.

          --
          Ben.

          Comment

          • Bart van Ingen Schenau

            #6
            Re: How to get array size from a pointer?

            On 8 okt, 15:11, "ggngu...@gmail .com" <ggngu...@gmail .comwrote:
            It's part of a test and I'm stumped. There is a function
            >
            void foo(char **x)
            >
            The function signature is given and cannot be changed, so no passing
            of other values. The test case involves defining this variable:
            >
            char *y[] = { /* bunch of stuff */ }
            >
            and calling
            >
            foo(y)
            >
            In the above, "bunch of stuff" is a series of triplets, two strings
            followed by a null string ("").
            There is no such thing as a null string.
            The string literal "" denotes an empty string, which is a string that
            contains only the terminating '\0' character.
            However, the last triplet ends with an
            integer 0. This seems that it's supposed to signify the end of the
            array. However, it appears to me that 0 is the same binary value as
            for the empty string (NUL, \0, whatever). So in effect, one cannot
            test for it as a sentry value because it's actually the same as the
            preceding triplets.
            First, the binary representation of a null pointer (what you get when
            using 0 in a *pointer* context) is not required to be all-bits-zero
            (although it often is).

            The way you can detect if you are dealing with an empty string or a
            null pointer is like this:
            * Each string, including empty strings, has an address that is
            distinct from NULL.
            * When using strings, you are alweays passing around the addresses of
            the strings.
            >
            How then, can the function foo() determine the bounds of the array?
            Knowing the bounds of the particular test case is not sufficient since
            the actual test suite may have arrays of varying size.
            If you iterate over x, then *x == NULL indicates the end of the array.
            **x == '\0' indicates an empty string (if *x != NULL).

            Bart v Ingen Schenau

            Comment

            • James Kuyper

              #7
              Re: How to get array size from a pointer?

              Bartc wrote:
              >
              <ggnguser@gmail .comwrote in message
              news:3798e9c5-5247-40bc-a52c-d30c73cdcdc9@o4 0g2000prn.googl egroups.com...
              >It's part of a test and I'm stumped. There is a function
              >>
              >void foo(char **x)
              >>
              >The function signature is given and cannot be changed, so no passing
              >of other values. The test case involves defining this variable:
              >>
              >char *y[] = { /* bunch of stuff */ }
              >>
              >and calling
              >>
              >foo(y)
              >>
              >In the above, "bunch of stuff" is a series of triplets, two strings
              >followed by a null string (""). However, the last triplet ends with an
              >integer 0. This seems that it's supposed to signify the end of the
              >array. However, it appears to me that 0 is the same binary value as
              >for the empty string (NUL, \0, whatever). So in effect, one cannot
              >test for it as a sentry value because it's actually the same as the
              >preceding triplets.
              >
              Any empty string is not necessarily NULL.
              He wrote NUL, not NULL. NUL is the name for an ASCII character which is
              written '\0' in C (when the character set is ASCII).

              Referring to what you said, rather than what he was talking about:

              NULL is necessarily not a an empty string. The only byte in an empty
              string has a null character (NUL on ASCII systems). If NULL expands to
              an expression with arithmetic type, it will certainly compare equal to
              that null character; even if NULL has a pointer type, it will probably
              compare equal to a null character on most systems - (void*)0 is required
              to be a null pointer, but (void*)i is not required to produce the same
              result, even if i==0 (though it usually does).

              However, NULL will never compare equal to an empty string. An empty
              string has a pointer type, and points at the array containing the null
              character which terminates it. In any such comparison, NULL converts to
              a null pointer of the same type, and a null pointer is prohibited from
              comparing equal to any pointer to an actual object.
              { "ABC","","GHI", 0}
              >
              Three non-NULL strings followed by a NULL.
              >
              (vippstar will say NULL is not the same as 0. ...
              vippstar is correct. It could be (void*)0, or (8-8) or '\0', among many
              other possibilities. They will all compare equal to 0, however.
              ... Whatever; if all you have
              to mark the end is 0, then use it and hope that on your system 0 will
              never be a legal string pointer.)
              0 is a null pointer constant. When it appears in a pointer context, it
              is treated as a null pointer. A null pointer can never compare equal to
              a pointer to any actual object or pointer. It is legal for a system to
              have a pointer whose bits are all 0 that is not a null pointer. However,
              on such a system, such a pointer can NOT be produced by initializing a
              pointer object with a null pointer constant.

              Comment

              • Bartc

                #8
                Re: How to get array size from a pointer?


                <vippstar@gmail .comwrote in message
                news:31929414-332e-4c5a-a63d-7a4968a6a32f@r3 7g2000prr.googl egroups.com...
                On Oct 8, 4:22 pm, "Bartc" <b...@freeuk.co mwrote:
                ><ggngu...@gmai l.comwrote in message
                >>
                >news:3798e9c 5-5247-40bc-a52c-d30c73cdcdc9@o4 0g2000prn.googl egroups.com...
                >>
                >>
                >>
                It's part of a test and I'm stumped. There is a function
                >>
                void foo(char **x)
                >>
                The function signature is given and cannot be changed, so no passing
                of other values. The test case involves defining this variable:
                >>
                char *y[] = { /* bunch of stuff */ }
                >>
                and calling
                >>
                foo(y)
                >>
                In the above, "bunch of stuff" is a series of triplets, two strings
                followed by a null string (""). However, the last triplet ends with an
                integer 0. This seems that it's supposed to signify the end of the
                array. However, it appears to me that 0 is the same binary value as
                for the empty string (NUL, \0, whatever). So in effect, one cannot
                test for it as a sentry value because it's actually the same as the
                preceding triplets.
                >>
                >Any empty string is not necessarily NULL.
                >
                An empty string is _never_ NULL.
                I missed where the OP mentioned the null string "", and assumed that NULL
                was also being used to signify an empty string.

                However NULL to represent an empty string can be a useful technique
                (although not recognised by standard functions), hence my comment.
                >
                >{ "ABC","","GHI", 0}
                >>
                >Three non-NULL strings followed by a NULL.
                >
                What is a non-NULL string? A string can't be NULL! That doesn't make
                sense.
                Isn't that what I said? A string that is not NULL.
                >(vippstar will say NULL is not the same as 0. Whatever; if all you have
                >to
                >mark the end is 0, then use it and hope that on your system 0 will never
                >be
                >a legal string pointer.)
                >
                B?ll?cks.
                So eloquent.

                --
                Bartc

                Comment

                • James Kuyper

                  #9
                  Re: How to get array size from a pointer?

                  Bartc wrote:
                  >
                  <vippstar@gmail .comwrote in message
                  news:31929414-332e-4c5a-a63d-7a4968a6a32f@r3 7g2000prr.googl egroups.com...
                  >On Oct 8, 4:22 pm, "Bartc" <b...@freeuk.co mwrote:
                  ....
                  >>Any empty string is not necessarily NULL.
                  >>
                  >An empty string is _never_ NULL.
                  >
                  I missed where the OP mentioned the null string "", and assumed that
                  NULL was also being used to signify an empty string.
                  >
                  However NULL to represent an empty string can be a useful technique
                  (although not recognised by standard functions), hence my comment.
                  No, NULL can be used to represent a missing string. An empty string is a
                  string containing one null character; NULL does not qualify.
                  >>{ "ABC","","GHI", 0}
                  >>>
                  >>Three non-NULL strings followed by a NULL.
                  >>
                  >What is a non-NULL string? A string can't be NULL! That doesn't make
                  >sense.
                  >
                  Isn't that what I said? A string that is not NULL.
                  But all strings are not NULL, so that's a pointless phrase. Just say
                  "Three strings followed by a null pointer".

                  Comment

                  • Erik Trulsson

                    #10
                    Re: How to get array size from a pointer?

                    ggnguser@gmail. com <ggnguser@gmail .comwrote:
                    It's part of a test and I'm stumped. There is a function
                    >
                    void foo(char **x)
                    >
                    The function signature is given and cannot be changed, so no passing
                    of other values. The test case involves defining this variable:
                    >
                    char *y[] = { /* bunch of stuff */ }
                    >
                    and calling
                    >
                    foo(y)
                    >
                    In the above, "bunch of stuff" is a series of triplets, two strings
                    followed by a null string (""). However, the last triplet ends with an
                    integer 0. This seems that it's supposed to signify the end of the
                    array. However, it appears to me that 0 is the same binary value as
                    for the empty string (NUL, \0, whatever). So in effect, one cannot
                    test for it as a sentry value because it's actually the same as the
                    preceding triplets.
                    >
                    How then, can the function foo() determine the bounds of the array?
                    Knowing the bounds of the particular test case is not sufficient since
                    the actual test suite may have arrays of varying size.
                    An empty string ("") is represented as a pointer to a NUL byte (i.e. a byte
                    that has the value 0)
                    (A string is a pointer to a character array that is terminated by a NUL byte)

                    A plain 0 interpreted as a pointer is a null pointer which is different.


                    If a particular entry compares equal to NULL then it is a null pointer
                    (which in your case would indicate the end of your array 'y' of char
                    pointers.) If it does not compare equal to NULL, but points to a byte having
                    the value 0, then it is an empty string. (The remaining possibilities are
                    that it points to a non-NULL string, or that it is an invalid pointer in
                    which case you did something wrong.)





                    --
                    <Insert your favourite quote here.>
                    Erik Trulsson
                    ertr1013@studen t.uu.se

                    Comment

                    • Richard Heathfield

                      #11
                      Re: How to get array size from a pointer?

                      ggnguser@gmail. com said:
                      It's part of a test and I'm stumped. There is a function
                      >
                      void foo(char **x)
                      >
                      The function signature is given and cannot be changed, so no passing
                      of other values. The test case involves defining this variable:
                      >
                      char *y[] = { /* bunch of stuff */ }
                      >
                      and calling
                      >
                      foo(y)
                      >
                      In the above, "bunch of stuff" is a series of triplets, two strings
                      followed by a null string (""). However, the last triplet ends with an
                      integer 0. This seems that it's supposed to signify the end of the
                      array. However, it appears to me that 0 is the same binary value as
                      for the empty string (NUL, \0, whatever). So in effect, one cannot
                      test for it as a sentry value because it's actually the same as the
                      preceding triplets.
                      >
                      How then, can the function foo() determine the bounds of the array?
                      Knowing the bounds of the particular test case is not sufficient since
                      the actual test suite may have arrays of varying size.

                      Your English description of the array contents is confusing. I suggest you
                      show us the actual initialisation code - i.e. replace /* bunch of stuff */
                      with the actual bunch of actual stuff.


                      --
                      Richard Heathfield <http://www.cpax.org.uk >
                      Email: -http://www. +rjh@
                      Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                      "Usenet is a strange place" - dmr 29 July 1999

                      Comment

                      • lawrence.jones@siemens.com

                        #12
                        Re: How to get array size from a pointer?

                        ggnguser@gmail. com <ggnguser@gmail .comwrote:
                        >
                        However, it appears to me that 0 is the same binary value as
                        for the empty string (NUL, \0, whatever).
                        No. An empty string is like an empty box; a null pointer is no box at
                        all.
                        --
                        Larry Jones

                        Rats. I can't tell my gum from my Silly Putty. -- Calvin

                        Comment

                        • Keith Thompson

                          #13
                          Re: How to get array size from a pointer?

                          "Bartc" <bc@freeuk.comw rites:
                          <vippstar@gmail .comwrote in message
                          news:31929414-332e-4c5a-a63d-7a4968a6a32f@r3 7g2000prr.googl egroups.com...
                          >On Oct 8, 4:22 pm, "Bartc" <b...@freeuk.co mwrote:
                          [...]
                          >>Any empty string is not necessarily NULL.
                          >>
                          >An empty string is _never_ NULL.
                          >
                          I missed where the OP mentioned the null string "", and assumed that
                          NULL was also being used to signify an empty string.
                          >
                          However NULL to represent an empty string can be a useful technique
                          (although not recognised by standard functions), hence my comment.
                          [...]

                          Sure, you can use a null pointer to represent an empty string. You
                          can also use the number 42, or the string "this is an empty string",
                          to represent an empty string. You can use anything you like to
                          represent anything you like, as long as you're consistent about it.

                          But a null pointer *is not* an empty string, and it doesn't point to
                          an empty string. And, in my opinion, using a null pointer to
                          represent an empty string is a bad idea; it's too easy to accidentally
                          pass it to a function that doesn't know about your convention, and it
                          loses you the ability to distinguish between an empty string and the
                          absence of a string.

                          Finally, strings are not pointers. A pointer can point to a string; a
                          pointer cannot be a string.

                          --
                          Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                          Nokia
                          "We must do something. This is something. Therefore, we must do this."
                          -- Antony Jay and Jonathan Lynn, "Yes Minister"

                          Comment

                          • lovecreatesbeauty@gmail.c0m

                            #14
                            Re: How to get array size from a pointer?

                            On Oct 9, 12:48 am, Keith Thompson <ks...@mib.orgw rote:
                            >
                            But a null pointer *is not* an empty string, and it doesn't point to
                            an empty string. And, in my opinion, using a null pointer to
                            represent an empty string is a bad idea; it's too easy to accidentally
                            pass it to a function that doesn't know about your convention, and it
                            loses you the ability to distinguish between an empty string and the
                            absence of a string.
                            >
                            Finally, strings are not pointers. A pointer can point to a string; a
                            pointer cannot be a string.
                            >
                            Yes. In my opinion, the null/empty string is this string: ""; the null
                            pointer is this value: NULL.

                            Comment

                            • Keith Thompson

                              #15
                              Re: How to get array size from a pointer?

                              "lovecreatesbea uty@gmail.c0m" <lovecreatesbea uty@gmail.comwr ites:
                              On Oct 9, 12:48 am, Keith Thompson <ks...@mib.orgw rote:
                              >But a null pointer *is not* an empty string, and it doesn't point to
                              >an empty string. And, in my opinion, using a null pointer to
                              >represent an empty string is a bad idea; it's too easy to accidentally
                              >pass it to a function that doesn't know about your convention, and it
                              >loses you the ability to distinguish between an empty string and the
                              >absence of a string.
                              >>
                              >Finally, strings are not pointers. A pointer can point to a string; a
                              >pointer cannot be a string.
                              >
                              Yes. In my opinion, the null/empty string is this string: ""; the null
                              pointer is this value: NULL.
                              Yes -- but it's not a matter of opinion.

                              [news.motzarella .org was having problems, which seem to have been
                              cleared up; sorry if this appears twice.]

                              --
                              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                              Nokia
                              "We must do something. This is something. Therefore, we must do this."
                              -- Antony Jay and Jonathan Lynn, "Yes Minister"

                              Comment

                              Working...