Array of Structures

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

    Array of Structures

    Hello I have a structure called Company.

    struct Company
    {
    char *employee;
    char *employee_addre ss;
    };

    I want to build an array of this structure but the number of employees
    will change thorughout the course the programs use so it will need to
    be dynamic.

    I know I need to first allocate the structure and then allocate the
    array of structures but I am confussed on how to do this.

    In my program I am doing the following

    Also for right now I am using

    #Define count = 100; until I get the count function setup properly to
    get the exact count in the future

    void u_setup_company _array(int employee_number )
    {
    int q;
    struct Company CompArray;

    /*Allocate the array structure */
    CompArray= (struct Company ) malloc(count* sizeof(struct Company
    *));

    /*if bad allocation then return */
    if(!CompArray)
    {
    return;
    }

    /*allocate the array and set the variables to Null */
    for(q = 0; q<= count ; h++)
    {
    CompArray[q] = (struct Company ) malloc(sizeof(C ompArray));
    CompArray[q]->employee= NULL;
    CompArray[q]->employee_addre ss= NULL;
    }


    /*Once the array is allocated then I pass it and the employee
    number to the other function */
    status = build_company_a rray(employe_nu mber, CompArray);
    <----Should this be &ComArray instead?


    In another module I would have the function build_company_a rray


    long build_company_a rray(int employee_number , structure CompArray)
    {
    /* Read the database and find a match on the employee number */
    int counter = 0;
    while (database_emp#)
    {

    if (database_emp# == employee_number )
    {
    CompArray[count]employee = getName(employe e_number);
    CompArray[count]employee_addres s =
    getAddress(empl oyee_number);
    counter++;
    }
    }
    return 0;
    }

    I guess my questions pertain to proper allocation of the structure and
    the array. It's a simple straight forward structure so I don't think I
    need to make it a pointer to a structure do I?

    Anyway

    1) Am I defining my structure properly in my initial function? Should
    it be struct Company CompArray; or struct Company *CompArray;

    2) Am I allocating the structure properly?
    3) Am I allocating the array properly?
    4) Am I passing the array properly so that when it returns it will be
    populated with the right values that it built in the called function?

    What I want to do is setup the array in the first u_setup_company _array
    function pass the allocated array to the build_company_a rray function
    in the other module. Once in the other module I populate it. When it
    comes returns to the u_setup_company _array function then it will be
    populated and ready for use in the next step of the
    u_setup_company _array function

    Once done with everything in the array then I would get rid of it which
    i understand what to do there.

    can you guys help?

    Thanks
    Sam

    BTW I am using using c modules compiled in Visual Studios.Net

  • liorm

    #2
    Re: Array of Structures

    You have implemented CompArray as an array of pointers to Company
    (struct type), so CompArray should be declared as struct Company
    **CompArray. Pointer to pointer is actually array of pointers. I don't
    see any other issues with your code except for that.

    LM

    Comment

    • pete

      #3
      Re: Array of Structures

      Sam wrote:[color=blue]
      >
      > Hello I have a structure called Company.
      >
      > struct Company
      > {
      > char *employee;
      > char *employee_addre ss;
      > };[/color]
      [color=blue]
      > It's a simple straight forward structure so I don't think I
      > need to make it a pointer to a structure do I?[/color]

      I don't know what you mean.

      /* BEGIN new.c output */

      Fred
      11 Maiden Lane

      /* END new.c output */


      /* BEGIN new.c */

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>

      #define COUNT 100

      struct Company {
      char *employee;
      char *employee_addre ss;
      };

      void free_CompArray( struct Company *CompArray, size_t index);

      int main(void)
      {
      struct Company *CompArray;
      size_t index;
      int random;

      CompArray = malloc(COUNT * sizeof *CompArray);
      if (CompArray == NULL) {
      puts("CompArray == NULL");
      exit(EXIT_FAILU RE);
      }
      for (index = 0; index != COUNT; ++index) {
      CompArray[index].employee = NULL;
      CompArray[index].employee_addre ss = NULL;
      }
      random = rand() % COUNT;
      CompArray[random].employee = malloc(sizeof "Fred");
      if (CompArray[random].employee == NULL) {
      puts("CompArray[random].employee == NULL");
      exit(EXIT_FAILU RE);
      }
      CompArray[random].employee_addre ss
      = malloc(sizeof "11 Maiden Lane");
      if (CompArray[random].employee_addre ss == NULL) {
      puts("CompArray[random].employee_addre ss == NULL");
      exit(EXIT_FAILU RE);
      }
      strcpy(CompArra y[random].employee, "Fred");
      strcpy(CompArra y[random].employee_addre ss, "11 Maiden Lane");
      puts("/* BEGIN new.c output */\n");
      puts(CompArray[random].employee);
      puts(CompArray[random].employee_addre ss);
      free_CompArray( CompArray, COUNT);
      puts("\n/* END new.c output */");
      return 0;
      }

      void free_CompArray( struct Company *CompArray, size_t index)
      {
      const size_t count = index;

      for (index = 0; index != count; ++index) {
      free(CompArray[index].employee);
      free(CompArray[index].employee_addre ss);
      }
      free(CompArray) ;
      }

      /* END new.c */


      --
      pete

      Comment

      • Keith Thompson

        #4
        Re: Array of Structures

        "liorm" <liorm@ti.com > writes:[color=blue]
        > You have implemented CompArray as an array of pointers to Company
        > (struct type), so CompArray should be declared as struct Company
        > **CompArray. Pointer to pointer is actually array of pointers. I don't
        > see any other issues with your code except for that.[/color]

        Pleaes provide context. Read <http://cfaj.freeshell. org/google/> to
        see how and why.

        No, a pointer to pointer is not actually an array of pointers. Arrays
        are not pointers; pointers are not arrays. Please read section 6 of
        the comp.lang.c FAQ, <http://www.c-faq.com/>.

        --
        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

        • CBFalconer

          #5
          Re: Array of Structures

          Sam wrote:[color=blue]
          >
          > Hello I have a structure called Company.
          >
          > struct Company
          > {
          > char *employee;
          > char *employee_addre ss;
          > };
          >
          > I want to build an array of this structure but the number of
          > employees will change thorughout the course the programs use so
          > it will need to be dynamic.[/color]

          The structure would be better labelled "anemployee ". At any rate,
          the important thing is what sort of operations do you need to
          perform on these things? Which have to be fast? Which just have
          to be feasible? What items are you likely to add or remove? You
          will probably find that an array is not the right thing to hold the
          collection.

          I suspect you will find that a hash table will do all you want.
          There is one available under GPL at:

          <http://cbfalconer.home .att.net/download/hashlib.zip>

          --
          "If you want to post a followup via groups.google.c om, don't use
          the broken "Reply" link at the bottom of the article. Click on
          "show options" at the top of the article, then click on the
          "Reply" at the bottom of the article headers." - Keith Thompson
          More details at: <http://cfaj.freeshell. org/google/>
          Also see <http://www.safalra.com/special/googlegroupsrep ly/>


          Comment

          • Sam

            #6
            Re: Array of Structures

            Hello everybody base upon the information that I got from you guys I
            made the following changes

            struct EmpInfo
            {
            char *employee;
            char *employee_addre ss;
            };

            void u_setup_empinfo _array(int employee_number )
            {
            int q;
            struct EmpInfo *EmpArray;


            count = u_emp_count(emp loyee_number); <--- Counter comes back with
            500
            employees from a read on the database count where the
            employee numbers
            match
            if(!count)
            {
            return;
            }

            /*Allocate the array structure */
            EmpArray= malloc(count * sizeof *EmpArray);

            if(!EmpArray)
            {
            return;
            }

            for(q = 0; h< count ; q++)
            {
            EmpArray[q]->employee= NULL;
            EmpArray[q]->employee_addre ss= NULL;
            }

            /*Get the array of employee info*/
            status = build_empinfo_a rray(employee_n umber, EmpArray)

            if(status)
            {
            for(h = 0; h< count ; h++)
            {
            free(EmpArray[q]->employee);
            free(EmpArray[q]->employee_addre ss);
            }
            free(cm8tablena me);
            return;
            }
            else
            {
            .......do something with it the array
            }

            /*Clean up the array - no longer need it */
            for(h = 0; h< count ; h++)
            {
            free(EmpArray[q]->employee);
            free(EmpArray[q]->employee_addre ss);
            }
            free(cm8tablena me);
            return
            }

            long build_empinfo_a rray(int employee_number , EmpInfo *EmpArray)
            {
            int count = 0;
            while (database_emp#)
            {

            if (database_emp# == employee_number )
            {
            EmpArray[count]employee = (char
            *)malloc(sizeof (getName(employ ee_number)));
            EmpArray[count]employee = getName(employe e_number);
            EmpArray[count]employee_addres s = (char
            *)malloc(sizeof (getAddress

            (employee_numbe r)));
            EmpArray[count]employee_addres s =
            getAddress(empl oyee_number);
            count++;
            }
            }
            return 0;
            }



            u_emp_count(int employee_number )
            {
            int count = 0;
            while (database_emp#)
            {

            if (database_emp# == employee_number )
            {
            count++;
            }
            }
            return count;
            }
            The arrary comes back to the calling function and the array appears to
            be built correctly with the name and the address of the employee

            The problem that when I am done with the array I want to clear it and
            free it but it crashes on the first line of the clean

            /*Clean up the array - no longer need it */
            for(h = 0; h< count ; h++)
            {
            free(EmpArray[q]->employee); <-------------------- crashes
            here
            free(EmpArray[q]->employee_addre ss);
            }
            free(cm8tablena me);

            Ass I said the array looks to have been built correctly and you can see
            that prior to the data being placed in the employee variable it is
            malloc'ed with the size of what it gets back from the call. Then I do
            the same call to just get the data into the variable. Something tells
            me that I am still not allocating something properly but what - Advice?

            Thanks
            Sam





            pete wrote:[color=blue]
            > Sam wrote:[color=green]
            > >
            > > Hello I have a structure called Company.
            > >
            > > struct Company
            > > {
            > > char *employee;
            > > char *employee_addre ss;
            > > };[/color]
            >[color=green]
            > > It's a simple straight forward structure so I don't think I
            > > need to make it a pointer to a structure do I?[/color]
            >
            > I don't know what you mean.
            >
            > /* BEGIN new.c output */
            >
            > Fred
            > 11 Maiden Lane
            >
            > /* END new.c output */
            >
            >
            > /* BEGIN new.c */
            >
            > #include <stdio.h>
            > #include <stdlib.h>
            > #include <string.h>
            >
            > #define COUNT 100
            >
            > struct Company {
            > char *employee;
            > char *employee_addre ss;
            > };
            >
            > void free_CompArray( struct Company *CompArray, size_t index);
            >
            > int main(void)
            > {
            > struct Company *CompArray;
            > size_t index;
            > int random;
            >
            > CompArray = malloc(COUNT * sizeof *CompArray);
            > if (CompArray == NULL) {
            > puts("CompArray == NULL");
            > exit(EXIT_FAILU RE);
            > }
            > for (index = 0; index != COUNT; ++index) {
            > CompArray[index].employee = NULL;
            > CompArray[index].employee_addre ss = NULL;
            > }
            > random = rand() % COUNT;
            > CompArray[random].employee = malloc(sizeof "Fred");
            > if (CompArray[random].employee == NULL) {
            > puts("CompArray[random].employee == NULL");
            > exit(EXIT_FAILU RE);
            > }
            > CompArray[random].employee_addre ss
            > = malloc(sizeof "11 Maiden Lane");
            > if (CompArray[random].employee_addre ss == NULL) {
            > puts("CompArray[random].employee_addre ss == NULL");
            > exit(EXIT_FAILU RE);
            > }
            > strcpy(CompArra y[random].employee, "Fred");
            > strcpy(CompArra y[random].employee_addre ss, "11 Maiden Lane");
            > puts("/* BEGIN new.c output */\n");
            > puts(CompArray[random].employee);
            > puts(CompArray[random].employee_addre ss);
            > free_CompArray( CompArray, COUNT);
            > puts("\n/* END new.c output */");
            > return 0;
            > }
            >
            > void free_CompArray( struct Company *CompArray, size_t index)
            > {
            > const size_t count = index;
            >
            > for (index = 0; index != count; ++index) {
            > free(CompArray[index].employee);
            > free(CompArray[index].employee_addre ss);
            > }
            > free(CompArray) ;
            > }
            >
            > /* END new.c */
            >
            >
            > --
            > pete[/color]

            Comment

            • Sam

              #7
              Re: Array of Structures

              Hello everybody base upon the information that I got from you guys I
              made the following changes

              struct EmpInfo
              {
              char *employee;
              char *employee_addre ss;
              };

              void u_setup_empinfo _array(int employee_number )
              {
              int q;
              struct EmpInfo *EmpArray;


              count = u_emp_count(emp loyee_number); <--- Counter comes back with
              500
              employees from a read on the database count where the
              employee numbers
              match
              if(!count)
              {
              return;
              }

              /*Allocate the array structure */
              EmpArray= malloc(count * sizeof *EmpArray);

              if(!EmpArray)
              {
              return;
              }

              for(q = 0; h< count ; q++)
              {
              EmpArray[q]->employee= NULL;
              EmpArray[q]->employee_addre ss= NULL;
              }

              /*Get the array of employee info*/
              status = build_empinfo_a rray(employee_n umber, EmpArray)

              if(status)
              {
              for(h = 0; h< count ; h++)
              {
              free(EmpArray[q]->employee);
              free(EmpArray[q]->employee_addre ss);
              }
              free(cm8tablena me);
              return;
              }
              else
              {
              .......do something with it the array
              }

              /*Clean up the array - no longer need it */
              for(h = 0; h< count ; h++)
              {
              free(EmpArray[q]->employee);
              free(EmpArray[q]->employee_addre ss);
              }
              free(cm8tablena me);
              return
              }

              long build_empinfo_a rray(int employee_number , EmpInfo *EmpArray)
              {
              int count = 0;
              while (database_emp#)
              {

              if (database_emp# == employee_number )
              {
              EmpArray[count]employee = (char
              *)malloc(sizeof (getName(employ ee_number)));
              EmpArray[count]employee = getName(employe e_number);
              EmpArray[count]employee_addres s = (char
              *)malloc(sizeof (getAddress

              (employee_numbe r)));
              EmpArray[count]employee_addres s =
              getAddress(empl oyee_number);
              count++;
              }
              }
              return 0;
              }



              u_emp_count(int employee_number )
              {
              int count = 0;
              while (database_emp#)
              {

              if (database_emp# == employee_number )
              {
              count++;
              }
              }
              return count;
              }
              The arrary comes back to the calling function and the array appears to
              be built correctly with the name and the address of the employee

              The problem that when I am done with the array I want to clear it and
              free it but it crashes on the first line of the clean

              /*Clean up the array - no longer need it */
              for(h = 0; h< count ; h++)
              {
              free(EmpArray[q]->employee); <-------------------- crashes
              here
              free(EmpArray[q]->employee_addre ss);
              }
              free(cm8tablena me);

              Ass I said the array looks to have been built correctly and you can see
              that prior to the data being placed in the employee variable it is
              malloc'ed with the size of what it gets back from the call. Then I do
              the same call to just get the data into the variable. Something tells
              me that I am still not allocating something properly but what - Advice?

              Thanks
              Sam

              pete wrote:[color=blue]
              > Sam wrote:[color=green]
              > >
              > > Hello I have a structure called Company.
              > >
              > > struct Company
              > > {
              > > char *employee;
              > > char *employee_addre ss;
              > > };[/color]
              >[color=green]
              > > It's a simple straight forward structure so I don't think I
              > > need to make it a pointer to a structure do I?[/color]
              >
              > I don't know what you mean.
              >
              > /* BEGIN new.c output */
              >
              > Fred
              > 11 Maiden Lane
              >
              > /* END new.c output */
              >
              >
              > /* BEGIN new.c */
              >
              > #include <stdio.h>
              > #include <stdlib.h>
              > #include <string.h>
              >
              > #define COUNT 100
              >
              > struct Company {
              > char *employee;
              > char *employee_addre ss;
              > };
              >
              > void free_CompArray( struct Company *CompArray, size_t index);
              >
              > int main(void)
              > {
              > struct Company *CompArray;
              > size_t index;
              > int random;
              >
              > CompArray = malloc(COUNT * sizeof *CompArray);
              > if (CompArray == NULL) {
              > puts("CompArray == NULL");
              > exit(EXIT_FAILU RE);
              > }
              > for (index = 0; index != COUNT; ++index) {
              > CompArray[index].employee = NULL;
              > CompArray[index].employee_addre ss = NULL;
              > }
              > random = rand() % COUNT;
              > CompArray[random].employee = malloc(sizeof "Fred");
              > if (CompArray[random].employee == NULL) {
              > puts("CompArray[random].employee == NULL");
              > exit(EXIT_FAILU RE);
              > }
              > CompArray[random].employee_addre ss
              > = malloc(sizeof "11 Maiden Lane");
              > if (CompArray[random].employee_addre ss == NULL) {
              > puts("CompArray[random].employee_addre ss == NULL");
              > exit(EXIT_FAILU RE);
              > }
              > strcpy(CompArra y[random].employee, "Fred");
              > strcpy(CompArra y[random].employee_addre ss, "11 Maiden Lane");
              > puts("/* BEGIN new.c output */\n");
              > puts(CompArray[random].employee);
              > puts(CompArray[random].employee_addre ss);
              > free_CompArray( CompArray, COUNT);
              > puts("\n/* END new.c output */");
              > return 0;
              > }
              >
              > void free_CompArray( struct Company *CompArray, size_t index)
              > {
              > const size_t count = index;
              >
              > for (index = 0; index != count; ++index) {
              > free(CompArray[index].employee);
              > free(CompArray[index].employee_addre ss);
              > }
              > free(CompArray) ;
              > }
              >
              > /* END new.c */
              >
              >
              > --
              > pete[/color]

              Comment

              • Thad Smith

                #8
                Re: Array of Structures

                Sam wrote:[color=blue]
                > Hello I have a structure called Company.
                >
                > struct Company
                > {
                > char *employee;
                > char *employee_addre ss;
                > };[/color]

                As Charles Falconer suggests, your structure name is misleading. Consider

                struct employee
                {
                char *name;
                char *address;
                };

                The point is that your nomenclature should not be misleading to the code
                reader.
                [color=blue]
                > I want to build an array of this structure but the number of employees
                > will change thorughout the course the programs use so it will need to
                > be dynamic.[/color]

                Here are some choices:
                1. array declared with fixed size (simplest)
                2. array allocated at run time with size which doesn't change after
                allocation (malloc/calloc)
                3. array allocated at run time that can vary during execution (malloc +
                realloc)
                4. dynamic list or tree structure (dynamic allocation with pointers
                linking elements)
                [color=blue]
                > I know I need to first allocate the structure and then allocate the
                > array of structures but I am confussed on how to do this.[/color]

                No. If you allocate an array of structures, you don't need to allocate
                individual structures.
                [color=blue]
                > In my program I am doing the following
                >
                > Also for right now I am using
                >
                > #Define count = 100; until I get the count function setup properly to
                > get the exact count in the future[/color]

                That's
                #define count 100

                [color=blue]
                > void u_setup_company _array(int employee_number )
                > {
                > int q;
                > struct Company CompArray;
                >
                > /*Allocate the array structure */
                > CompArray= (struct Company ) malloc(count* sizeof(struct Company
                > *));[/color]

                If you want to allocate the array at run time, you need to declare a
                pointer to the structure:
                struct employee *CompArray;

                Your allocation will work. The canonical form recommended in this forum is
                CompArray = malloc (count * sizeof (*CompArray));

                Using a pointer to the destination pointer as the sizeof operand helps
                to ensure (an be obvious) that you are using the correct type. Also,
                casting the results of malloc is recommended against in C to allow
                errors to be reported (if, for example, a prototype for malloc has not
                be seen).
                [color=blue]
                > /*if bad allocation then return */
                > if(!CompArray)
                > {
                > return;
                > }[/color]

                It's wise to check, but consider the affect on the function caller.
                There is no indication to either the calling code or the user (via
                stderr or stdout) that an error occurred or what it was.
                [color=blue]
                > /*allocate the array and set the variables to Null */
                > for(q = 0; q<= count ; h++)[/color]
                q?[color=blue]
                > {
                > CompArray[q] = (struct Company ) malloc(sizeof(C ompArray));[/color]

                No. The space for the struct has already been allocated with the array.
                You should eliminate this.
                [color=blue]
                > CompArray[q]->employee= NULL;[/color]
                ^^ should be .
                [color=blue]
                >
                > /*Once the array is allocated then I pass it and the employee
                > number to the other function */
                > status = build_company_a rray(employe_nu mber, CompArray);
                > <----Should this be &ComArray instead?[/color]

                No, unless the function will possibly reallocate the array and set the
                new array address. If so, you would declare it differently and specify
                a different functionality.
                [color=blue]
                >
                >
                > In another module I would have the function build_company_a rray
                >
                >
                > long build_company_a rray(int employee_number , structure CompArray)[/color]
                This should be struct employee *CompArray ^^^^^^^^^^^^[color=blue]
                > {
                > /* Read the database and find a match on the employee number */
                > int counter = 0;
                > while (database_emp#)[/color]

                You cannot use "#" as part of a variable name in C.
                [color=blue]
                > {
                >
                > if (database_emp# == employee_number )
                > {
                > CompArray[count]employee = getName(employe e_number);
                > CompArray[count]employee_addres s =
                > getAddress(empl oyee_number);
                > counter++;
                > }
                > }
                > return 0;
                > }
                >
                > I guess my questions pertain to proper allocation of the structure and
                > the array. It's a simple straight forward structure so I don't think I
                > need to make it a pointer to a structure do I?[/color]

                That depends on what you want to do. You can declare a structure or an
                array of structures without declaring a pointer. If you want to
                dynamically allocate an array, you either need to declare a pointer or
                use a C99 variable size array.
                [color=blue]
                > 1) Am I defining my structure properly in my initial function? Should
                > it be struct Company CompArray; or struct Company *CompArray;[/color]

                Since you are dynamically allocating the array (which is not required
                for the fixed size), you must declare a pointer to the struct.
                [color=blue]
                > 2) Am I allocating the structure properly?[/color]
                [color=blue]
                > 3) Am I allocating the array properly?[/color]

                The structure array is allocated properly. The individual element
                allocation is not.
                [color=blue]
                > 4) Am I passing the array properly so that when it returns it will be
                > populated with the right values that it built in the called function?[/color]

                You are calling properly, but not declaring the function properly.
                [color=blue]
                > can you guys help?[/color]

                We try. ;=)

                --
                Thad

                Comment

                Working...