Thread: Help with seg fault error initializing an array of structs inside a struct

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    16

    Help with seg fault error initializing an array of structs inside a struct

    Hi guys,
    I am trying to create an array of structs and then initialize values in the array of structs contained within each node. I keep getting a segmentation fault error when the program tries to add a node to the internal array of structs.

    I can't figure out if the problem is in how I am allocating memory to the external array of structs or a bug in the code for adding an node to the internal array of structs. The code is pasted below.

    Any thoughts or suggestions for how I can pinpoint the error would be greatly appreciated. Many thanks in advance for your help.

    Code:
    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    /* C LIBRARIES -------------------------------------------------------------- */
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include <errno.h>
    
    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    /* ANIMAL STRUCTURE --------------------------------------------------------- */
    struct animal_node
    {
      int age; 
      int prod_type; 
      struct animal_node *next_node; 
    };
    
    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    /* FARM STRUCTURE ----------------------------------------------------------- */
    struct farm_node
    {
      struct animal_node *anim_list[12]; 
      int anim_counts[12]; 
    };
    
    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    /* GLOBAL FUNCTION DEFINITIONS ---------------------------------------------- */
      extern struct farm_node **create_farm_list();
      extern struct animal_node *add_anim_to_list();
    
      extern void destroy_anim_list();
      extern void visualize_list(); 
    
    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    /* GLOBAL VARIABLE DEFINITIONS ---------------------------------------------- */
       long int num_farms = 500;
       long int num_prod_types = 12;
    
    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    /* MAIN PROGRAM ------------------------------------------------------------- */
    int main(void)
    {
      long int i, x;
      
      /* CREATE FARM LIST */
      struct farm_node **farm_list = NULL;  
      farm_list = create_farm_list(num_farms, farm_list); 
       
      /* VISUALIZE INFORMATION FROM A SAMPLE LIST */
       visualize_list( farm_list[0] -> anim_list[0]); 
        
     /* FREE MEMORY */
      for(i = 0; i < num_farms; i++)
        {
          for(x = 0; x < num_prod_types; x++)
           {      
              destroy_anim_list(farm_list[i]->anim_list[x]);
           }
          free(farm_list[i]); 
        }
       free(farm_list); 
    
    system ("pause");
    return(0);   
    }
    
    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    /* FUNCTION DEFINITIONS ------------------------------------------------ */
    
    
    /* -------------------------------------------------------------------------- */
    /* create_farm_list: CREATE ARRAY OF FARM STRUCTS AND INITIALIZE ANIMAL LISTS */
    /* -------------------------------------------------------------------------- */
    extern struct farm_node **create_farm_list(long int num_farms, struct farm_node **farm_list)
    {     
        
        long int i = 0;
        int x = 0;
     
        struct animal_node *new_node; 
        farm_list = (struct farm_node **)malloc( sizeof(struct farm_node *) * (num_farms));
        
       if(farm_list == NULL)
          {
                 printf("Cannot allocate memory.\n");
                 exit(1);
          }
       else
          {       
              for(i = 0; i < num_farms; i++)
                 {        
                   farm_list[i] = (struct farm_node *)malloc(sizeof(struct farm_node));
               
                   for(x = 0; x < num_prod_types; x++)
                    {
                       farm_list[i] -> anim_counts[x] = 0;
                       
                       new_node = (struct animal_node*)malloc(sizeof( struct animal_node ));                    
                       new_node -> age = -33333;
                       new_node -> prod_type = 99;
                       new_node->next_node = NULL;
                       farm_list[i]->anim_list[x] = add_anim_to_list(new_node, farm_list[i]->anim_list[x]);
       
                       new_node = (struct animal_node*)malloc(sizeof( struct animal_node )); 
                       new_node -> age = 33333;
                       new_node -> prod_type = 99;
                       new_node-> next_node = NULL;
                       farm_list[i]->anim_list[x] = add_anim_to_list(new_node, farm_list[i]->anim_list[x]);
                     }
    
                  } 
            }            
        
       return(farm_list);
       
    } 
    /* -------------------------------------------------------------------------- */
    
    /* -------------------------------------------------------------------------- */
    /* ADD NODE TO LIST OR CREATE IF IT DOESN'T EXIST  -------------------------- */
    /* -------------------------------------------------------------------------- */
    struct animal_node *add_anim_to_list(struct animal_node *node_to_add,  struct animal_node *list)
    {  
        if(list == NULL)
         {
           list = node_to_add;
           return (list);
         }
        else
         {
            struct animal_node *current_node1;
            struct animal_node *prev_node1;
    
            current_node1 = list;
            prev_node1 = list;
            
             while (current_node1 -> next_node != NULL)
               {
                  if(current_node1 -> age <= node_to_add -> age) {break;}
                  prev_node1 = current_node1;
                  current_node1 = current_node1 -> next_node;    
               }
    
            if(current_node1 == list)
               {
                  if( current_node1 -> age <= node_to_add -> age)
                    {;
                     node_to_add -> next_node = current_node1;
                     list = node_to_add;
                    }
                  else
                   {
                     node_to_add -> next_node = current_node1 -> next_node;
                     current_node1 -> next_node = node_to_add;
                   }
               }
            else
               {       
                  if(current_node1 -> next_node != NULL)
                    {
                      prev_node1 -> next_node = node_to_add;
                      node_to_add -> next_node = current_node1;
                    }
                  else
                    {
                       if( current_node1 -> age <= node_to_add -> age)
                         {
                            prev_node1 -> next_node = node_to_add;
                            node_to_add -> next_node = current_node1;            
                         }
                       else
                         {
                           current_node1 -> next_node = node_to_add;              
                         }
                    } 
               }
           }
    return (list);
     }
    /* -------------------------------------------------------------------------- */
    
    /* -------------------------------------------------------------------------- */
    /* FREE MEMORY FROM LIST ---------------------------------------------------- */
    /* -------------------------------------------------------------------------- */
    void destroy_anim_list(struct animal_node *list)
    {   
         
       struct animal_node *current_node1;
       struct animal_node *new_node1;
         if(list != NULL)
         {
           current_node1 = list;
           while(current_node1 != NULL)
             {
               new_node1 = current_node1 -> next_node;
               free(current_node1);
               current_node1 = new_node1;
             } 
         }
       
    }
    /* -------------------------------------------------------------------------- */
    
    /* -------------------------------------------------------------------------- */
    /* VISUALIZE INFORMATION FROM LINKED LIST ----------------------------------- */
    /* -------------------------------------------------------------------------- */
    
    void visualize_list(struct animal_node *list)  
    {
    
    struct animal_node *current_node1;
    
       current_node1 = list;
       if(list != NULL)
       {
         while(current_node1 != NULL)
          {
             if(current_node1 -> prod_type == 99)
                 {
                     current_node1 = current_node1 -> next_node;  
                 }
             else
                {
                    printf("%d ", current_node1 -> age);
                    current_node1 = current_node1 -> next_node;  
                }              
          }                 
         printf("\n");
       }
       else
       {
           printf("No animals\n");
       }
     
    }
    /* -------------------------------------------------------------------------- */
    Last edited by NotAProgrammer; 07-28-2012 at 05:33 AM.

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You've forgotten to initialise the anim_list's to NULL at the same time you zero the anim_counts:
    Code:
    farm_list[i] -> anim_counts[x] = 0;
    farm_list[i] -> anim_list[x] = NULL;
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by NotAProgrammer View Post
    I am trying to create an array of structs...
    Code:
    /* CREATE FARM LIST */
    struct farm_node **farm_list = NULL;
    Out of curiosity: Why do you use a pointer to pointer to struct when you want to create an array of structs? And why do you call it "farm_list"?
    Code:
    struct farm_node *farms = malloc(sizeof(*farms) * num_farms);
    will allocate room for num_farms of struct farm_nodes, in other words you can treat this memory block as an array of struct farm_nodes.
    Additionally you need 2KB (4 * 500) more memory for your extra pointers to pointers which you just dereference to get to the struct members. Granted, this isn't a problem nowadays but it's still unnecessary consumed memory and an additional error source.

    Bye, Andreas

  4. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    16
    Thanks! - initializing the anim_list array values to NULL did the trick and I definitely would not have spotted that without your help so much appreciated.

    I can't remember why I originally set up farm_list as a pointer to an array of pointers. I think it was because this is part of a much larger program where I pass the farm structs individually into a complex series of functions to be modified and it was easier to pass the pointer as an argument with my limited understanding of C.
    Last edited by NotAProgrammer; 07-30-2012 at 08:21 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting array of struct inside struct
    By blueboyz in forum C Programming
    Replies: 13
    Last Post: 04-24-2012, 02:15 AM
  2. Initializing an array inside of a structure
    By Lima in forum C Programming
    Replies: 6
    Last Post: 06-08-2009, 08:53 PM
  3. Replies: 2
    Last Post: 06-07-2009, 08:49 AM
  4. Initializing array of structs
    By Nerigazh in forum C Programming
    Replies: 3
    Last Post: 11-20-2007, 12:26 AM
  5. initializing char array inside a struct
    By panos in forum C Programming
    Replies: 6
    Last Post: 06-01-2007, 06:43 PM