Problems with realloc on array of pointers

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • roguefeebo
    New Member
    • Apr 2007
    • 8

    Problems with realloc on array of pointers

    I'm very new to programming so be gentle, :(

    Essentially what I would like to do is to have a single function to be able to create a dynamic array of pointers to a struct so that I can have a modular menu system up and running. My menus will have several varying numbers of options. This is the first time I've worked with something like this and just can't get it worked out.

    I've snipped a lot of unnecessary code to this smaller piece so I can work out the data flow. These are the exact same kinds of errors I get in the larger program though.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct menuStruct
    {
      char question[100];
      void *menuCommand;
      struct menuStruct *nextMenu[];
    }; //end menuStruct
    typedef struct menuStruct *searchNameMenu[1];
    
    
    
    void addMenuItem(menuStruct **menu[], char question[], void menuCommand(), menuStruct **nextMenu[])
    {
    int i = 0;
    menuStruct *newOption;
    
    newOption = malloc(sizeof(menuStruct));
    strncpy(newOption->question, question, 100);
    newOption->menuCommand = menuCommand;
    newOption->nextMenu = &nextMenu;
    
    menu = realloc(menu, ((sizeof(menu[]) + sizeof(menuStruct*)));
    
    while(menu[i] != NULL)
      i++;
    
    *menu[i] = newOption;
    } //end function addMenuItem
    
    
    
    void initSearchNameMenu()
    {
    
    addMenuItem(searchNameMenu, "Search names by name.", searchNameDB_Name, NULL);
    addMenuItem(searchNameMenu, "Return to Previous Menu.", returnPrevMenu, NULL);
    addMenuItem(searchNameMenu, "Return to Main Menu.", returnMainMenu, NULL);
    } //end function initSearchNameDBMenu
    As you can tell from the errors, I'm fairly lost. The errors I get are:



    Code:
    c:12: error: syntax error before '*' token
    c:12: error: syntax error before '*' token
    c:15: warning: data definition has no type or storage class
    c:17: error: conflicting types for 'newOption'
    c:15: error: previous declaration of 'newOption' was here
    c:17: warning: initialization makes integer from pointer without a cast
    c:17: error: initializer element is not constant
    c:17: warning: data definition has no type or storage class
    c:18: error: syntax error before '->' token
    c:18: warning: conflicting types for built-in function 'strncpy'
    c:18: warning: data definition has no type or storage class
    c:19: error: syntax error before '->' token
    c:22: error: syntax error before ']' token
    c:22: error: syntax error before ')' token
    c:22: error: syntax error before ';' token
    c:22: warning: data definition has no type or storage class
    c:27: error: `i' undeclared here (not in a function)
    c:27: warning: data definition has no type or storage class
    c:28: error: syntax error before '}' token
    c: In function `initSearchNameMenu':
    c:35: error: syntax error before "searchNameMenu"
    c:36: error: syntax error before "searchNameMenu"
    c:37: error: syntax error before "searchNameMenu"
    c: At top level:
    c:12: error: storage size of `menuStruct' isn't known
    c:27: error: storage size of `menu' isn't known
    I'm lost in a maze of array, pointers, and void pointers, :( As far as the error on line 27, I'm not sure why 'i' is undeclared as I have it and use it in the function before that.

    Thanks for any help you can give!
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Code:
    typedef struct menuStruct *searchNameMenu[1];
    
    void addMenuItem(menuStruct **menu[], char question[], void menuCommand(), menuStruct **nextMenu[])
    {
    ...
    }
    The first 2 obvious things I would say are that

    1. I think you are probably trying to create a variable called searchNameMenu (that is how you use it later in the code) in the first line here but because of the typedef at the start of the line you actually are definiting a new type.

    In the addMenuItem function the definition of the first parameter causes it to have a type of menuStruct ***, I do not think I have ever seen a situation that required a pointer to a pointer to a pointer and I suspect this is an error.


    As a tip if you are getting lost in pointers I find thinking in 'int's, or typedefing the pointer can help. i.e. you have a menuStruct ** to work with, this is a pointer to a type, in this case it is a pointer to menuStruct * but how would the code work if it was just a pointer to and int (i.e. replace menuStruct * with int in you head) or alternatively typedef menuStruct * to something (say menuStructPoint er) to remove a level of *s.

    Comment

    • roguefeebo
      New Member
      • Apr 2007
      • 8

      #3
      Thanks a bunch, that helped a lot!
      Based on your suggestions I changed the code to:

      Code:
      #include <stdio.h>
      #include <stdlib.h>
      
      struct menuStruct
      {
        char question[100];
        void *menuCommand;
        struct menuStruct *nextMenu[];
      }; //end menuStruct
      typedef struct menuStruct *menuStructPtr;
      menuStructPtr searchNameMenu[1];
      
      void searchNameDB_Name();
      void addMenuItem(menuStructPtr menu[], char question[], void menuCommand(), menuStructPtr nextMenu[]);
      
      int main()
      {
          
      }
      
      void addMenuItem(menuStructPtr menu[], char question[], void menuCommand(), menuStructPtr nextMenu[])
      {
      int i = 0;
      menuStructPtr newOption;
      
      newOption = malloc(sizeof(menuStructPtr));
      strncpy(newOption->question, question, 100);
      newOption->menuCommand = menuCommand;
      newOption->nextMenu = nextMenu;
      
      menu = realloc(menu, ((sizeof(menu) + sizeof(menuStructPtr)));
      
      while(menu[i] != NULL)
        i++;
      
      menu[i] = newOption;
      } //end function addMenuItem
      
      
      
      void initSearchNameMenu()
      {
      
      addMenuItem(searchNameMenu, "Search names by name.", searchNameDB_Name, NULL);
      } //end function initSearchNameDBMenu
      
      void searchNameDB_Name()
      {
           
           }
      And now the only errors I get that I can't figure out are:
      Code:
      In function `addMenuItem':
      c:29: error: invalid use of flexible array member
      c:31: error: syntax error before ';' token
      Thanks again!

      Comment

      • ilikepython
        Recognized Expert Contributor
        • Feb 2007
        • 844

        #4
        Originally posted by roguefeebo
        Thanks a bunch, that helped a lot!
        Based on your suggestions I changed the code to:

        Code:
        #include <stdio.h>
        #include <stdlib.h>
        
        struct menuStruct
        {
          char question[100];
          void *menuCommand;
          struct menuStruct *nextMenu[];
        }; //end menuStruct
        typedef struct menuStruct *menuStructPtr;
        menuStructPtr searchNameMenu[1];
        
        void searchNameDB_Name();
        void addMenuItem(menuStructPtr menu[], char question[], void menuCommand(), menuStructPtr nextMenu[]);
        
        int main()
        {
            
        }
        
        void addMenuItem(menuStructPtr menu[], char question[], void menuCommand(), menuStructPtr nextMenu[])
        {
        int i = 0;
        menuStructPtr newOption;
        
        newOption = malloc(sizeof(menuStructPtr));
        strncpy(newOption->question, question, 100);
        newOption->menuCommand = menuCommand;
        newOption->nextMenu = nextMenu;
        
        menu = realloc(menu, ((sizeof(menu) + sizeof(menuStructPtr)));
        
        while(menu[i] != NULL)
          i++;
        
        menu[i] = newOption;
        } //end function addMenuItem
        
        
        
        void initSearchNameMenu()
        {
        
        addMenuItem(searchNameMenu, "Search names by name.", searchNameDB_Name, NULL);
        } //end function initSearchNameDBMenu
        
        void searchNameDB_Name()
        {
             
             }
        And now the only errors I get that I can't figure out are:
        Code:
        In function `addMenuItem':
        c:29: error: invalid use of flexible array member
        c:31: error: syntax error before ';' token
        Thanks again!
        For the second you need to add another parenthesis in:
        Code:
        menu = realloc(menu, ((sizeof(menu) + sizeof(menuStructPtr))));
        or
        Code:
        menu = realloc(menu, (sizeof(menu) + sizeof(menuStructPtr)));

        Comment

        • roguefeebo
          New Member
          • Apr 2007
          • 8

          #5
          Excellent. I have no idea how I missed it, I guess I was questioning my use of realloc on the array more than looking at the simple stuff.

          I'm trying to research the first error more without luck so far. I'll see if I can find something that explains it pretty well, but feel free to point something to me.

          Comment

          • roguefeebo
            New Member
            • Apr 2007
            • 8

            #6
            I've got a couple more questions at the bottom you may want to read first so you know what you're looking for. I have changed the code a bit from yesterday:
            Code:
            #include <stdio.h>
            #include <stdlib.h>
            
            struct menuStruct
            {
              char question[100];
              void *menuCommand;
              struct menuStruct *nextMenu;
            }; //end menuStruct
            typedef struct menuStruct *menuStructPtr;
            menuStructPtr searchNameMenu[0];
            
            void initSearchNameMenu();
            void searchNameDB_Name();
            void addMenuItem(menuStructPtr menu[], char question[], void menuCommand(), menuStructPtr nextMenu[]);
            
            int main()
            {
                initSearchNameMenu();
                
                return 0;
            }
            
            void addMenuItem(menuStructPtr menu[], char question[], void menuCommand(), menuStructPtr nextMenu[])
            {
              int i = 0;
              menuStructPtr newOption;
            
              newOption = malloc(sizeof(menuStructPtr));
              strncpy(newOption->question, question, 100);
              newOption->menuCommand = menuCommand;
              //newOption->nextMenu = nextMenu;
            
              printf("%d", i);
              printf("%s", searchNameMenu[i]->question);
              system("pause");
            
              menu = realloc(menu, (sizeof(menu) + sizeof(menuStructPtr)));
            
              while(menu[i] != NULL)
                i++;
            
              printf("%d", i);
              printf("%s", searchNameMenu[i]->question);
              system("pause");
            
              menu[i] = newOption;
            
              printf("%d", i);
              printf("%s", searchNameMenu[i]->question);
              system("pause");
            } //end function addMenuItem
            
            
            
            void initSearchNameMenu()
            {
              addMenuItem(searchNameMenu, "Search names by name.", searchNameDB_Name, NULL);
              addMenuItem(searchNameMenu, "Search names by percentage occurrence.", searchNameDB_Name, NULL);
              addMenuItem(searchNameMenu, "Search names by length.", searchNameDB_Name, NULL);
            } //end function initSearchNameDBMenu
            
            void searchNameDB_Name()
            {
                 
            }
            So no more error regarding flexible array types by making nextMenu a pointer to another variable of type menuStruct * instead of an undefined array.

            I now get a warning of incompatible pointer types in the line

            Code:
            //newOption->nextMenu = nextMenu;
            when it's not commented out. I thought it was assigning a menuStruct * to a menuStruct * typedef so they would be the same type, but I can't seem to work out a way to get rid of the warning. Are they really a compatible type that the compiler isn't recognizing due to not being able to use the typedef within the struct definition?

            The bigger problem right now is that when the line is commented out, the code compiles fine and when running it, it prints out the first two items and then flat out crashes (without an error report pop-up from windows like a crash usually does). You can see I've tried debugging it, testing those variables, but the variables are being printed out correctly until the crash on the third statement in the initSearchNameM enu function.

            Can anyone give me any insight as to why the program is crashing on the third call to addMenuItem within initSearchNameM enu?

            Comment

            • roguefeebo
              New Member
              • Apr 2007
              • 8

              #7
              I found my "bigger" problem that was just a malloc on the pointer instead of a struct variable type. I still can't figure out the warning for incompatible pointer types, but it runs for now!

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                Your structure defines

                void *menuCommand;

                which is a data pointer but you assign a function pointer to it, try

                void (*menuCommand)( );

                Comment

                Working...