Thread: Two-dimensional arrays with strings

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    140

    Two-dimensional arrays with strings

    Hi

    When I have the following,

    Code:
    char strarr[][4] = {"hi", "all"};
    then is it correct that str[0] is the pointer to the first char in "hi"?

    Best,
    Niles.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    No, it is not a pointer.

    strarr[0] is an array of 4 characters, "hi\0\0"
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    But using

    printf("%s", strarr[0]);

    outputs "hi", and the "handle" of a string is the pointer to its first element? I.e., I thought that strarr[0] is also the pointer to the first char.

    Where am I wrong in my reasoning?

  4. #4
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Another way of looking at it: (*(*strarr)) == str[0][0], hence &(*(*strarr)) is the address of 'h' in "hi\0\0". But &(*(*strarr)) == *strarr, i.e. *strarr is the address of 'h'.

    Correct?

  5. #5
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Niels_M View Post
    Hi

    When I have the following,

    Code:
    char strarr[][4] = {"hi", "all"};
    then is it correct that str[0] is the pointer to the first char in "hi"?

    Best,
    Niles.
    Yep! that's correct

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You're getting confused by when an array is an array, and when it decays into a pointer to the first element of the array.

    Perhaps some examples for illustration
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #if 0
    
     arr1
    +---+---+---+---+---+---+---+---+---+---+---+---+
    | h | i | . | . | . | . | a | l | l | . | . | . |
    +---+---+---+---+---+---+---+---+---+---+---+---+
    arr1 is just 12 bytes of contiguous memory
    
      arr2
    +------+    +---+---+---+
    |      |--->| h | i | . |
    +------+    +---+---+---+---+
    |      |--->| a | l | l | . |
    +------+    +---+---+---+---+
    arr2 is 3 separate blocks of memory which could be anywhere in memory in relation
    to one another.  There is the array of pointers itself, and the separate
    storage for each string.
    
    #endif
    
    int main ( ) {
        char    arr1[][6] = { "hi", "all" };
        char    *arr2[] = { "hi", "all" };
        // sizeof tests
        {
            printf("%lu %lu\n", (unsigned long)sizeof(arr1[0]), (unsigned long)sizeof(arr2[0]) );
        }
        // pointer tests
        {
            char    *p1 = arr1[0];          // arr1[0] is an array, which decays to a pointer to the 1st element
            char    *p2 = arr2[0];          // pointer to start of first string
            printf("%s %s\n", p1, p2 );
            printf("%s %s\n", arr1[0], arr2[0] );   // arr1[0] is a decaying array
        }
        // pointer tests
        // pointing at the whole array returns a DIFFERENT pointer type.
        // Most specifically, it is NOT a char** as one might assume.
        {
            char    (*p1)[6] = &arr1[0];    // pointer to an array of 6 chars
            char    **p2 = &arr2[0];        // pointer to a pointer
            printf("%s %s\n", *p1, *p2 );
        }
    
        return 0;
    }
    And read this (both of you)
    Arrays and Pointers
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Salem View Post
    You're getting confused by when an array is an array, and when it decays into a pointer to the first element of the array.
    IMHO, all i meant was that the interpretation of strarr[0] depends on the context in which it is used. Using it in a printf(), as the o/p did, means that strarr[0] decays to a pointer to its first element (&strarr[0][0]). For the sizeof operation it is a 4 element array of chars.
    Quote Originally Posted by Salem View Post
    Perhaps some examples for illustration
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #if 0
    
     arr1
    +---+---+---+---+---+---+---+---+---+---+---+---+
    | h | i | . | . | . | . | a | l | l | . | . | . |
    +---+---+---+---+---+---+---+---+---+---+---+---+
    arr1 is just 12 bytes of contiguous memory
    
      arr2
    +------+    +---+---+---+
    |      |--->| h | i | . |
    +------+    +---+---+---+---+
    |      |--->| a | l | l | . |
    +------+    +---+---+---+---+
    arr2 is 3 separate blocks of memory which could be anywhere in memory in relation
    to one another.  There is the array of pointers itself, and the separate
    storage for each string.
    
    #endif
    
    int main ( ) {
        char    arr1[][6] = { "hi", "all" };
        char    *arr2[] = { "hi", "all" };
        // sizeof tests
        {
            printf("%lu %lu\n", (unsigned long)sizeof(arr1[0]), (unsigned long)sizeof(arr2[0]) );
        }
        // pointer tests
        {
            char    *p1 = arr1[0];          // arr1[0] is an array, which decays to a pointer to the 1st element
            char    *p2 = arr2[0];          // pointer to start of first string
            printf("%s %s\n", p1, p2 );
            printf("%s %s\n", arr1[0], arr2[0] );   // arr1[0] is a decaying array
        }
        // pointer tests
        // pointing at the whole array returns a DIFFERENT pointer type.
        // Most specifically, it is NOT a char** as one might assume.
        {
            char    (*p1)[6] = &arr1[0];    // pointer to an array of 6 chars
            char    **p2 = &arr2[0];        // pointer to a pointer
            printf("%s %s\n", *p1, *p2 );
        }
    
        return 0;
    }
    And read this (both of you)
    Arrays and Pointers
    Again the interpretation of whether it is a char* or a char[] depends on the context in which it is used.

  8. #8
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    I must admit I am a little confused of when an array decays to a pointer to the 1st element. In sizeof it does not, in printf it does.

    Is there a general rule? And thank you for the detailed example; it concretized my knowledge.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    sizeof is an operator - which by the way, only works on arrays declared in its current scope.
    printf is a function, not an operator. All arrays passed to functions are passed as a pointer to the first element of the array being passed; i.e., the address of the first element of the array.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Niels, note what Quzah referred to in his post:

    If you use sizeof(Array), in a function that was passed Array in a parameter, then you will ONLY get the sizeof(some pointer), NOT the sizeof() the array.

    Sizeof() only works on local (automatic), arrays when used in their "home" function. That and the non-contiguous memory of pointers (like Salem showed in Array2), always freaks out beginners in C. OK, the memory bit, still makes me scratch my head occasionally.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Is there a general rule? And thank you for the detailed example; it concretized my knowledge.
    Yes, question 6.3 of the FAQ I pointed you to lists them.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Quote Originally Posted by Salem View Post
    > Is there a general rule? And thank you for the detailed example; it concretized my knowledge.
    Yes, question 6.3 of the FAQ I pointed you to lists them.
    Thanks. They say that:

    >> (The exceptions are when the array is the operand of a sizeof or & operator, or is a string literal initializer for a character array. [...])

    In your example in post #6 you have

    Code:
    char    *p1 = arr1[0];          // arr1[0] is an array, which decays to a pointer to the 1st element
    You say arr1[0] decays - but wasn't that an exception?

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > You say arr1[0] decays - but wasn't that an exception?
    The & later on is one of the exceptions (&arr1[0])
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Quote Originally Posted by Salem View Post
    > You say arr1[0] decays - but wasn't that an exception?
    The & later on is one of the exceptions (&arr1[0])
    In that case I don't understand what the following exception is:

    "The exceptions are when the array is the operand of a sizeof or & operator, or is a string literal initializer for a character array."

    Can you please make an example stating this exception? This was it is impossible for me to misunderstand it,

    I really appreciate all your help - I am learning a lot from this thread (bookmarked!).

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    char str[] = "Hello World!";
    str does not decay.
    "My string" is actually an array of 13 characters. It does not decay to a pointer when initializing the array.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting two dimensional arrays
    By ejjjjj in forum C Programming
    Replies: 5
    Last Post: 05-30-2010, 11:38 AM
  2. quick sort arrays of strings
    By nik2 in forum C Programming
    Replies: 5
    Last Post: 04-25-2010, 02:01 PM
  3. Replies: 2
    Last Post: 02-23-2004, 06:34 AM
  4. strings or character arrays
    By Shadow12345 in forum C++ Programming
    Replies: 2
    Last Post: 07-21-2002, 10:55 AM
  5. Two dimensional arrays
    By Jax in forum C Programming
    Replies: 1
    Last Post: 11-07-2001, 12:53 PM