Thread: Two dimensional array of struct.

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    68

    Two dimensional array of struct.

    I define
    Code:
    typedef struct
    {
        uint32_t menu_id;
        char *menu_text;
    }MENU_ITEM;
    
    typedef struct
    {
        uint32_t menu_id;
        uint8_t * menu_text;
        MENU_ITEM *submenu;
    }MENU;
    And initialization
    Code:
    MENU_ITEM sub_menu_maint[] = { {0, "NULL"}, {1, "IBITS"}, {2, "SW VER"}, {3, "CONFIG"}, {4, "UPLOAD"} };
    MENU_ITEM sub_menu_fails[] = { {0, "NULL"}, {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}, { 3, "BACK"} };
    
    
    MENU menu[] =
    {
        { 0,  "     "    ,  NULL                    },  //DEFAULT
        { 1, "FAILS "  , sub_menu_fails     },
        { 2, "MAINT"  , sub_menu_maint  },
    };
    Now I need two dimensional array
    Code:
    typedef struct
    {
        uint32_t menu_id;
        uint8_t * menu_text;
        MENU_ITEM **submenu;
    }MENU;
    
    static MENU_ITEM sub_menu_fails[2][] =
    {
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}, { 3, "BACK"} },
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}  }
    };
    I get an error
    array type has incomplete element type

    But I can not to define it like sub_menu_fails[2][4] because the second dimention varies.
    What should I do?
    Last edited by john7; 07-22-2018 at 06:21 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > But I can not to define it like sub_menu_fails[2][4] because the second dimention varies.
    But you have no choice.
    Arrays by their nature have the same size in all the minor dimensions.

    > What should I do?
    Something similar to your first approach, where you have pointers to each variable-length sub-menu array.
    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
    May 2011
    Posts
    68
    Quote Originally Posted by Salem View Post
    > But I can not to define it like sub_menu_fails[2][4] because the second dimention varies.
    But you have no choice.
    Arrays by their nature have the same size in all the minor dimensions.

    > What should I do?
    Something similar to your first approach, where you have pointers to each variable-length sub-menu array.
    But this
    Code:
    MENU_ITEM *submenu;
    MENU_ITEM sub_menu_fails[] = { {0, "NULL"}, {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}, { 3, "BACK"} };
    And this
    Code:
    MENU_ITEM **submenu;
    static MENU_ITEM sub_menu_fails[][] =
    {
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}, { 3, "BACK"} },
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}  }
    };
    Isn't it the same approach?
    In both cases I'm setting the size while initializing the struct.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by john7
    Isn't it the same approach?
    In both cases I'm setting the size while initializing the struct.
    No, in the former you're saying that you have a number of MENU_ITEM objects with which you intend to initialise the array, and you're leaving the compiler to figure out that number. In the latter, you're saying that you have a number of arrays of an unknown number of arrays of MENU_ITEM objects... but in C the compiler isn't required to try and figure out what is that unknown number of inner arrays, especially since the syntax allows for the inner braces to be omitted, e.g., this is permitted:
    Code:
    int xs[][2] = {1, 2, 3, 4, 5, 6};
    and would be equivalent to:
    Code:
    int xs[][2] = {{1, 2}, {3, 4}, {5, 6}};
    As such, the same approach would be:
    Code:
    static MENU_ITEM sub_menu_fails[][4] =
    {
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}, { 3, "BACK"} },
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}  }
    };
    That is, you're saying that you have a number of arrays of 4 arrays of MENU_ITEM objects, and you're leaving the compiler to figure out that number from the initialisation.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    68
    Quote Originally Posted by laserlight View Post
    No, in the former you're saying that you have a number of MENU_ITEM objects with which you intend to initialise the array, and you're leaving the compiler to figure out that number. In the latter, you're saying that you have a number of arrays of an unknown number of arrays of MENU_ITEM objects... but in C the compiler isn't required to try and figure out what is that unknown number of inner arrays, especially since the syntax allows for the inner braces to be omitted, e.g., this is permitted:
    Code:
    int xs[][2] = {1, 2, 3, 4, 5, 6};
    and would be equivalent to:
    Code:
    int xs[][2] = {{1, 2}, {3, 4}, {5, 6}};
    As such, the same approach would be:
    Code:
    static MENU_ITEM sub_menu_fails[][4] =
    {
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}, { 3, "BACK"} },
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}  }
    };
    That is, you're saying that you have a number of arrays of 4 arrays of MENU_ITEM objects, and you're leaving the compiler to figure out that number from the initialisation.
    OK. This way
    Code:
    static MENU_ITEM sub_menu_fails[][4] =
    {
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}, { 3, "BACK"} },
        { {0, "MF"}, { 1, "HF"}, { 2, "FAILED"}  }
    };
    it compiles.
    But here
    Code:
    MENU menu[] =
    {
        { 0,  "     "    ,  NULL                    },  //DEFAULT
        { 1, "FAILS "  , sub_menu_fails     },
    };
    I get a warning
    (near initialization for 'menu[1].submenu') [enabled by default]

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Whilst [] decays to *, [][] does NOT decay to **.

    What you need at the moment is something like this
    MENU_ITEM (*submenu)[4];

    But I'm guessing that's not what you're really after.

    You would otherwise need an intermediate array of pointers like so.
    Code:
    static MENU_ITEM *sub_menu_fails_ptrs[] = {
        sub_menu_fails[0],
        sub_menu_fails[1],
    };
    
    MENU menu[] =
    {
        { 0,  "     "    ,  NULL                    },  //DEFAULT
        { 1, "FAILS "  , sub_menu_fails_ptrs     },
    };
    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
    May 2011
    Posts
    68
    Quote Originally Posted by Salem View Post
    Whilst [] decays to *, [][] does NOT decay to **.

    What you need at the moment is something like this
    MENU_ITEM (*submenu)[4];

    But I'm guessing that's not what you're really after.

    You would otherwise need an intermediate array of pointers like so.
    Code:
    static MENU_ITEM *sub_menu_fails_ptrs[] = {
        sub_menu_fails[0],
        sub_menu_fails[1],
    };
    
    MENU menu[] =
    {
        { 0,  "     "    ,  NULL                    },  //DEFAULT
        { 1, "FAILS "  , sub_menu_fails_ptrs     },
    };
    I see. Thank you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 06-19-2017, 04:46 AM
  2. Replies: 4
    Last Post: 09-02-2013, 11:19 AM
  3. Replies: 3
    Last Post: 03-03-2010, 03:35 PM
  4. 2 dimensional pointer array to a struct
    By AdamLAN in forum C++ Programming
    Replies: 5
    Last Post: 05-22-2005, 05:38 PM
  5. Replies: 3
    Last Post: 06-11-2002, 12:57 PM

Tags for this Thread