Link to home
Start Free TrialLog in
Avatar of welsh_boy
welsh_boy

asked on

Dealing with malloc'd structs

Hi guys, I am trying to code a game that tries to guess what object/animal/thing the user is thinking, i am using structs for the nodes in the tree.

Each struct has
a node number,
a nodetype,
a char array for an object & question - which can be empty,
a YES_ptr to another struct  - which can be empty,
a NO_ptr to another struct  - which can be empty,

When the game starts it checks whether the current node is an object or a question.
If it is an object it asks if the user was thinking of that object.
It it is a question, it asks that question, then according to the users response follows the appropriate pointer.

A restrictions
Please only use y and n for the answers, anything else wont work with the program at the moment.

My question is how to refer to the malloc'd nodes once they have been created.

E.g
When the program is first run it asks if you are thinking of a DOG?
If you say: n , And enter: e.g. a horse
it then asks for a question to distinguish between a horse and a dog
enter e.g. Does it gallop?
then it asks what is the answer for horse
enter y or n, it then sets the YES_ptr and NO_ptr for that question node appropriately.

This works fine for the first object you add.
Lets say now we are thinking of a lion
When you run it again it asks the previous question "Does it gallop?"
enter: n
it will ask if you are thinking of a DOG which is fine.
enter: n
It then asks what you were thinking
enter: lion
it then asks for a qeuestion to distinguish
e.g. enter : Does it have a main?
it then asks, what is the answer for a lion
if we enter: y (yes) it then sets the YES_ptr for that question to be lion, and it sets the NO_ptr to be Dog
but here i need to also change the previous question's (Does it gallop?)  NO_ptr to this new question, and I am not sure how to refer to the previously malloc'd struct.

I hope you understand what I mean. If you run my prog you will see my problem.

Thanks


#include <stdio.h>

struct node
{
     int nodetype; /*1 = question, 2 = object*/
     int nodenumber;
     char object[25];
     char question[25];
     struct node *YES_ptr;
     struct node *NO_ptr;
};

int main()
{
     struct node *new_ObjectNode,  *current_node, *new_questionNode, dog;
     char  buffer[255], buffer1[255];
     char *new_object1;
     char  user_input;
     char *new_object, *new_question;
     int nodecount = 1;
     
     /* HARD CODE AN OBJECT NODE */
     //struct node dog;

     dog.nodetype = 2;
     dog.nodenumber = 0;
     dog.YES_ptr = NULL;
     dog.NO_ptr = NULL;
     strcpy(dog.object, "Dog");
     
     //Allocate memory for the 2 new structs
     new_ObjectNode = (struct node*)malloc (sizeof(struct node));
     new_questionNode = (struct node*)malloc (sizeof(struct node));  
     
     printf("______________________________\n");
     printf("|                            |\n");      
     printf("|       GUESSING GAME        |\n");
     printf("|                            |\n");      
     printf("______________________________\n\n");      
     printf("Welcome to my game\nPlease thing of an object/animal/thing\n");
     printf("______________________________\n");
     
     //Set the current node to Dog when prog is first run
     current_node= &dog;
     
//Outer loop for game
     while (1)
     {
//Inner loop for  questions
       while (1)
       {
      
                //If we are at a question node
         if (current_node->nodetype == 1)
       {
          //ask the question
          printf("%s \n", current_node->question);
          fgetc(stdin);
          
          //Get answer from user
          scanf("%c", &user_input );
            user_input = toupper( user_input );
            //If answer is yes set current node to YES_ptr
          if(user_input == 'Y'){
               current_node = current_node->YES_ptr;
               }
          //If answer is no set current node to NO_ptr
            if(user_input == 'N'){
             current_node = current_node->NO_ptr;
            }
             
       }//if (question node)
      
      
         if (current_node->nodetype == 2)
      { //Object Node
            printf("Are you thinking of a %s?",current_node->object);
            fflush(stdin);
          scanf("%c", &user_input );
            user_input = toupper( user_input );
            if(user_input == 'Y')
         {
               printf("I win\n");
               break; //Break out of the loop
            }

            if(user_input == 'N')
         {
               printf("You Win .....\n");
               printf("What where you thinking?\n ");

               //Enter new object and question into a new node
     
               printf("Please Enter An Object \n");
               fgetc(stdin);
               new_object = fgets(buffer, 255, stdin);
               printf("You have entered: %s\n", new_object);
               memset(new_ObjectNode ->object, 0, 25);
             memcpy(new_ObjectNode ->object, new_object,24);
             new_ObjectNode ->nodetype = 2;
             new_ObjectNode ->nodenumber = nodecount+1;
             nodecount ++;
     
               printf("Please Enter A Question \n");          
               new_question = fgets(buffer, 255, stdin);
               memset(new_questionNode ->question, 0, 25);
             memcpy(new_questionNode ->question, new_question,24);               
             new_questionNode ->nodetype = 1;
             new_questionNode ->nodenumber = nodecount+1;
             nodecount ++;    
              
             //Ask a question to distinguish between the new object and
             //the current object
            
             printf("Is the answer for %s Yes?",new_ObjectNode->object);
               scanf("%c", &user_input );
               user_input = toupper( user_input );
            
             //Set the question's pointers according to user answer
               if(user_input == 'Y'){
               new_questionNode ->YES_ptr = new_ObjectNode;
               new_questionNode ->NO_ptr = current_node;
                 printf("Yes PTR: %s\n", new_questionNode->YES_ptr->object);
                 printf("No PTR: %s\n", new_questionNode->NO_ptr->object);
                 }  
               if(user_input == 'N'){
               new_questionNode ->NO_ptr = new_ObjectNode;
               new_questionNode ->YES_ptr = current_node;
                 printf("Yes PTR: %s\n", new_questionNode->YES_ptr->object);
                 printf("No PTR: %s\n", new_questionNode->NO_ptr->object);
                 }  
                            
               //printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
               //printf("Question You entered into struct is: %s \n", new_questionNode->question);
               
             //Set the current node to the new question node
             current_node= new_questionNode;
               break; //Break out of loop
           } // (User input N)
        
          else  printf("\007Error: Invalid choice\n");
     } // if (Object Node)
     

              
     }

     
     printf("Another Go?\n");        
     /*Get Response From User */
     scanf("  %c", &user_input );
     user_input = toupper( user_input );
 
     /*If answer is No exit*/
     if(user_input == 'N'){
       printf("Thanks for playing\n");
       break;
       }      
  }
}

Avatar of welsh_boy
welsh_boy

ASKER

sorry about some of the indentation, it has pasted in wrong!
sorry about the indetation, it lost some of it when pasted in
SOLUTION
Avatar of Karl Heinz Kremer
Karl Heinz Kremer
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ozo
#include <stdio.h>

struct node
{
     int nodetype; /*1 = question, 2 = object*/
     int nodenumber;
     char object[25];
     char question[25];
     struct node *YES_ptr;
     struct node *NO_ptr;
};

int main()
{
    struct node *new_ObjectNode,  *current_node, *new_questionNode, dog;
    struct node *root_node;
    char  buffer[255], buffer1[255];
    char *new_object1;
    char  user_input;
    char *new_object, *new_question;
    int nodecount = 1;
     
    /* HARD CODE AN OBJECT NODE */
    //struct node dog;

    dog.nodetype = 2;
    dog.nodenumber = 0;
    dog.YES_ptr = NULL;
    dog.NO_ptr = NULL;
    strcpy(dog.object, "Dog");
     
    //Allocate memory for the 2 new structs
     
    printf("______________________________\n");
    printf("|                            |\n");      
    printf("|       GUESSING GAME        |\n");
    printf("|                            |\n");      
    printf("______________________________\n\n");      
    printf("Welcome to my game\nPlease thing of an object/animal/thing\n");
    printf("______________________________\n");
     
    //Set the current node to Dog when prog is first run
    root_node= &dog;
//Outer loop for game
    while (1)
    {
//Inner loop for  questions
     current_node= root_node;
        while (1)
        {
     
            //If we are at a question node
            if( current_node->nodetype == 1 ){
                //ask the question
                printf("%s \n", current_node->question);
                //fgetc(stdin);
         
                //Get answer from user
                scanf(" %c", &user_input );
                user_input = toupper( user_input );
                //If answer is yes set current node to YES_ptr
                if( user_input == 'Y' ){
                    current_node = current_node->YES_ptr;
                }
                //If answer is no set current node to NO_ptr
                if( user_input == 'N' ){
                    current_node = current_node->NO_ptr;
                }
             
            }//if (question node)
     
            if( current_node->nodetype == 2 ){
                //Object Node
                printf("Are you thinking of a %s?",current_node->object);
                fflush(stdin);
                scanf(" %c", &user_input );
                user_input = toupper( user_input );
                if( user_input == 'Y' ){
                    printf("I win\n");
                    break; //Break out of the loop
                }

                if( user_input == 'N' ){
                     printf("You Win .....\n");
                     printf("What where you thinking?\n ");
 
                     //Enter new object and question into a new node
     
                     printf("Please Enter An Object \n");
                     fgetc(stdin);
                     new_object = fgets(buffer, 255, stdin);
                     printf("You have entered: %s\n", new_object);
                     new_ObjectNode = (struct node*)malloc (sizeof(struct node));
                     memset(new_ObjectNode ->object, 0, 25);
                     memcpy(new_ObjectNode ->object, new_object,24);
                     new_ObjectNode ->nodetype = 2;
                     new_ObjectNode ->nodenumber = nodecount+1;
                     nodecount ++;
     
                     printf("Please Enter A Question \n");          
                     new_question = fgets(buffer, 255, stdin);
                     new_questionNode = (struct node*)malloc (sizeof(struct node));  
                     memset(new_questionNode ->question, 0, 25);
                     memcpy(new_questionNode ->question, new_question,24);              
                     new_questionNode ->nodetype = 1;
                     new_questionNode ->nodenumber = nodecount+1;
                     nodecount ++;    
             
                     //Ask a question to distinguish between the new object and
                     //the current object
           
                      printf("Is the answer for %s Yes?",new_ObjectNode->object);
                      scanf(" %c", &user_input );
                      user_input = toupper( user_input );
           
                      //Set the question's pointers according to user answer
                      if( user_input == 'Y' ){
                           new_questionNode ->YES_ptr = new_ObjectNode;
                           new_questionNode ->NO_ptr = root_node;
                           printf("Yes PTR: %s\n", new_questionNode->YES_ptr->object);
                           printf("No PTR: %s\n", new_questionNode->NO_ptr->object);
                      }  
                     if( user_input == 'N' ){
                         new_questionNode ->NO_ptr = new_ObjectNode;
                         new_questionNode ->YES_ptr = root_node;
                         printf("Yes PTR: %s\n", new_questionNode->YES_ptr->object);
                         printf("No PTR: %s\n", new_questionNode->NO_ptr->object);
                      }  
                           
                       //printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
                       //printf("Question You entered into struct is: %s \n", new_questionNode->question);
               
                       //Set the current node to the new question node
                       root_node= new_questionNode;
                       break; //Break out of loop
                } // (User input N)      
                else  printf("\007Error: Invalid choice\n");
            } // if (Object Node)
        }
     
        printf("Another Go?\n");        
        /*Get Response From User */
        scanf(" %c", &user_input );
        user_input = toupper( user_input );
 
        /*If answer is No exit*/
        if( user_input == 'N' ){
             printf("Thanks for playing\n");
             break;
        }      
    }
}
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks kent, I am trying your approach, here is my changed code.
I have changed it so that it sets the YES and NO ptrs depending on the users input from the question he has entered.


Trouble is that I am now getting a segmentation fault
:(


printf("Please Enter A Question \n");          
               new_question = fgets(buffer, 255, stdin);
             struct node *NewNode = (struct node *)malloc (sizeof(struct node));
             NewNode->nodenumber ==nodecount ++;
               memcpy (NewNode, current_node, sizeof(struct node));

             
            //Ask a question to distinguish between the new object and
            //the current object
           
            printf("What is the answer for %s?",new_ObjectNode->object);
               scanf("%c", &user_input );
               user_input = toupper( user_input );
           
            //Set the question's pointers according to user answer
               if(user_input == 'Y'){
             current_node->YES_ptr = NewNode;
             current_node->NO_ptr = new_ObjectNode;
             current_node->nodetype = 1;
             strcpy (current_node->question, buffer);
                 printf("Yes PTR: %s\n", current_node->YES_ptr->object);
                 printf("No PTR: %s\n", new_questionNode->NO_ptr->object);
                 }  current_node
               if(user_input == 'N'){
             current_node->YES_ptr = new_ObjectNode;
             current_node->NO_ptr = NewNode;
             current_node->nodetype = 1;
             strcpy (current_node->question, buffer);
                 printf("Yes PTR: %s\n", current_node->YES_ptr->object);
                 printf("No PTR: %s\n", current_node->NO_ptr->object);
                 }  
                         
               //printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
               //printf("Question You entered into struct is: %s \n", new_questionNode->question);
               
            //Set the current node to the new question node
            //current_node= new_questionNode;
               break; //Break out of loop
           } // (User input N)
       
         else  printf("\007Error: Invalid choice\n");
     } // if (Object Node)
     

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

Your structure has fixed length buffers for both 'object' and 'question'.  Is the question that you're asking short enough to fit in 24 character?

Other than that, it's hard to tell exactly where the segmentation fault is occurring.  If you'll put a fflush(stdout); after each printf() we'll know the last print statement to get executed.


Kent
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks Friedrich, and Kdo for all the help.
Will ask santa for a C book!! :)
Hi welsh_boy,

Accepting an answer of "Go read a book" when you've got someone willingly assisting you defeats the spirit of these boards.

If you want to pursue this discussion, I'll be glad to continue walking you through the steps of finding and fixing the problems.  Both with code recommendations and detailed explanations.


Kent