Thread: Program Crashing

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    26

    Program Crashing

    I need help with my program. It's a search engine just like the guy's in the thread before mine. Here's the code:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    FILE *infile;
    char search[10][30]; 
    
    /* Structure used for BST */
    struct tree_node{
    	char data[30];
    	int count;
    	struct tree_node *left;
    	struct tree_node *right;
    };
    
    /* Structure used for Link List */
    struct node{
    	char lname[30];
    	char fname[30];
    	char title[50];
    	int hits[10];
    	int score;
    	struct tree_node *p;
    	struct node *next;
    } *list;
    
    /* Function Prototypes */
    void load();
    void addinfo(struct node **head, char lname[], char fname[], char title[]);
    void findspot(struct node **head, char data[], char lname[], char fname[], char title[]);
    void adddata(struct tree_node **p, char data[]);
    void printheight(struct node *head, char lname[], char fname[], char title[]);
    int findheight(struct tree_node *p);
    void printwords(struct node *head, char lname[], char fname[], char title[]);
    void print(struct tree_node *p);
    void query();
    void find(struct node **head, int count);
    int findhits(struct tree_node *p, int i);
    void findscore(struct node **head, int count);
    void printresults(struct node **head, int count);
    
    int main(){
    	int option;
    	
    	do{
    		/* Ask user pick option */
    		printf("List of options: \n");
    		printf("\t1. Load\n");
    		printf("\t2. Query\n");
    		printf("\t3. Quit\n");
    		printf("\nEnter choice: ");
    		scanf("%d", &option);
    	
    		/* Check option and do appropriate actions */
    		switch(option){
    			case 1: /* Load */
    				load();
    				break;
    		
    			case 2: /* Query */
    				query();
    				break;
    			
    			case 3: /* Quit */
    				printf("You have choosen Quit.\n");
    				break;
    	
    			default: /* Invalid */
    				printf("Invalid choice. Please try again.\n");
    				break;
    		}
    	}while(option != 3);
    	
    	return 0;	
    }
    
    void load(){
    	char file[30], fname[30], lname[30], title[50], data[30];
    	int i, j, num, words = 0, length;
    	
    	/*  Get name of load file */
    	do{
    		printf("Name the load file: ");
    		scanf("%s", file);
    		infile = fopen(file, "r");
    		putchar('\n');
    	}while(!infile);
    	
    	/* Get num of documents */
    	fscanf(infile, "%d", &num);
    	
    	/* Add info to documents */
    	for(i = 0; i < num; i++){
    		fscanf(infile, "%s %s", lname, fname);
    		fscanf(infile, "%s", title);
    		addinfo(&list, lname, fname, title);
    		
    		printf("%s\n", title);
    		fscanf(infile, "%s", data);
    	
    		while(strcmp(data, "DOCUMENT_OVER") != 0){
    			words++;
    			length = strlen(data);
    			
    			/* Make word lower case */
    			for(j = 0; j < length; j++){
    				data[j] = tolower(data[j]);	
    			}
    			
    			findspot(&list, data, lname, fname, title);
    			fscanf(infile, "%s", data);
    		}
    		
    		/* Print remaining info for document */
    		printf("%d words\n", words);
    		printheight(list, lname, fname, title);
    		printwords(list, lname, fname, title);
    	}
    	
    	fclose(infile);
    }
    
    /* Query the documents */
    void query(){
    	int count = 0;
    	char file[30], data[30];
    	
    	/* Open the query file */
    	do{
    		printf("Name the query file: ");
    		scanf("%s", file);
    		infile = fopen(file, "r");
    		putchar('\n');
    	}while(!infile);
    	
    	fscanf(infile, "%s", data);
    	
    	/* Read in all the words */
    	while(strcmp(data, "QUERY_OVER") != 0){
    		strcpy(search[count], data);
    		count++;
    		fscanf(infile, "%s", data);
    	}
    	
    	/* Find hits and scores then print results */
    	find(&list, count);
    	findscore(&list, count); 
    	printresults(&list, count);
    	
    	fclose(infile);
    }
    	
    /* Add First and Last name along with the title to the node */
    void addinfo(struct node **head, char lname[], char fname[], char title[]){
    	struct node *pNew, *pCur, *pNext;
    	
    	pNew = (struct node*) (malloc(sizeof(struct node)));
    	strcpy(pNew -> lname, lname);
    	strcpy(pNew -> fname, fname);
    	strcpy(pNew -> title, title);
    	pNew -> next = NULL;
    	pNew -> p = NULL;
    
    	/* check if the list is empty or if next node is empty */
    	if (*head == NULL)
    		*head = pNew;
    
    	else if((*head) -> next == NULL)
    		(*head) -> next = pNew;
    		
    	/* now examine the remaining list */
    	else {
    		pCur = *head;
            
    		while(pCur -> next != NULL){
    				pCur = pCur -> next ;
    		}
          
    		pCur -> next = pNew;
    	}
    }
    
    /* Find where to add the data */	
    void findspot(struct node **head, char data[], char lname[], char fname[], char title[]){
    	struct node *pCur;
    	pCur = *head;
    	
    	while(pCur != NULL){
    		/* Find the right node in the link list */
    		if(strcmp(pCur -> lname, lname) == 0 && strcmp(pCur -> fname, fname) == 0 && strcmp(pCur -> title, title) == 0){
    			/* Add data to the BST */
    			adddata(&pCur -> p, data);
    			break;
    		}
    		
    		pCur = pCur -> next;
    	};
    }
    
    /* Add data to the BST */
    void adddata(struct tree_node **p, char data[]){
    	struct tree_node *pNew, *pCur;
    	
    	pNew = (struct tree_node*)(malloc(sizeof(struct tree_node)));
    	strcpy(pNew -> data, data);
    	pNew -> count = 0;
    	pNew -> left = NULL;
    	pNew -> right = NULL;
    	
    	/* Check if NULL */
    	if(*p == NULL)
    		*p = pNew;
    		
    	pCur = *p;
    		
    	/* Check where to put the data */
    	if(strcmp(pCur -> data, data) == 0)
    		pCur -> count = (pCur -> count) + 1;
    		
    	if(strcmp(pCur -> data, data) < 0)
    		adddata(&pCur -> left, data);
    		
    	if(strcmp(pCur -> data, data) > 0)
    		adddata(&pCur -> right, data);
    }
    
    /* Print height of the BST */
    void printheight(struct node *head, char lname[], char fname[], char title[]){
    	struct node *pCur = head;
    	int height;
    	
    	/* If the list isn't null */
    	if(pCur != NULL){
    		if(strcmp(pCur -> lname, lname) == 0 && strcmp(pCur -> fname, fname) == 0 && strcmp(pCur -> title, title) == 0){
    			height = findheight(pCur -> p);
    			printf("Height %d\n", height);
    		}
    		
    		else 
    			printheight(pCur -> next, lname, fname, title);
    	}
    }
    
    /* Find the height of the BST */
    int findheight(struct tree_node *p){
    	int left, right;
    	
    	/* If null return 0 */
    	if(p == NULL) 
    		return 0;
    
    	left = 1 + findheight(p -> left); 
    	right = 1 + findheight(p -> right);
    
    	if (left > right) 
    		return left; 
    	else 
    		return right;
    } 
    
    /* Find correct node for BST */
    void printwords(struct node *head, char lname[], char fname[], char title[]){	
    	struct node *pCur;
    	pCur = head;
    	
    	/* If the list isn't null */
    	if(pCur != NULL){
    		if(strcmp(pCur -> lname, lname) == 0 && strcmp(pCur -> fname, fname) == 0 && strcmp(pCur -> title, title) == 0){
    			print(pCur -> p);
    			putchar('\n');
    			putchar('\n');
    		}
    		else 
    			printwords(pCur -> next, lname, fname, title);
    	}
    }
    
    /* Print the words in the BST */
    void print(struct tree_node *p){
    	struct tree_node *pCur = p;
    	
    	/* If p isn't null */
    	if(pCur != NULL){
    		if(pCur -> count > 1)
    			printf("%s(%d) ", pCur -> data, pCur -> count);
    		else if(pCur -> count == 1)
    			printf("%s ", pCur -> data);
    			
    		print(pCur -> left);
    		print(pCur -> right);
    	}
    	
    }
    
    /* Find the amount of hits */
    void find(struct node **head, int count){
    	struct node *pCur = *head;
    	int i;
    	
    	/* Assign the values */
    	while(pCur != NULL){
    		for(i = 0; i < count + 1; i++){
    			pCur -> hits[i] = findhits(pCur -> p, i);
    		}
    
    		pCur = pCur -> next;
    	}
    }	
    
    /* Return the amount of hits */
    int findhits(struct tree_node *p, int i){
    	struct tree_node *pCur = p;	
    	
    	if(strcmp(pCur -> data, search[i]) == 0)
    		return(pCur -> count);
    		
    	if(strcmp(pCur -> data, search[i]) < 0)
    		findhits(pCur -> left, i);
    		
    	if(strcmp(pCur -> data, search[i]) > 0)
    		findhits(pCur -> right, i);
    }
    
    /* Assign the scores */
    void findscore(struct node **head, int count){
    	struct node *pCur = *head;
    	int i, j, length;
    	char title[50];
    	
    	pCur -> score = 999;
    	
    	/* Assign the score based on hits */
    	while(pCur != NULL){
    		for(i = 0; i < count + 1; i++){
    			if(pCur -> hits[i] != 0){
    				if(pCur -> hits[i] < pCur -> score)
    					pCur -> score = pCur -> hits[i];
    			}
    		}
    		
    		pCur = pCur -> next;
    		pCur -> score = 999;
    	}
    	
    	pCur = *head;
    	
    	/* Add 10 if title matches */
    	while(pCur != NULL){
    		strcpy(title, pCur -> title);
    		length = strlen(title);
    			
    		/* Make word lower case */
    		for(j = 0; j < length; j++){
    			if(isalpha(title[j]) && isupper(title[j]))
    				title[j] = tolower(title[j]);	
    		}
    		
    		for(i = 0; i < count + 1; count++){
    			if(strcmp(title, search[i]) == 0);
    				pCur -> score = pCur -> score + 10;
    		}
    		
    		pCur = pCur -> next;
    	}
    }
    
    /* Print the results */
    void printresults(struct node **head, int count){
    	struct node *pNew = *head, *pCur = *head;
    	int i, highest = 0;
    	
    	while(pNew != NULL){
    		/* Find highest score */
    		while(pCur != NULL){
    			if(highest < pCur -> score)
    				highest = pCur -> score;
    		
    			pCur = pCur -> next;
    		}
    	
    		pCur = *head;
    	
    		/* If the score isn't 0 */
    		if(highest != 0){
    			while(pCur != NULL){
    				if(highest == pCur -> score)
    					break;
    				
    				pCur = pCur -> next;
    			}
    		
    			for(i = 0; i < count + 1; i++){
    				printf("%s ", search[i]);
    			}
    		
    			printf("\nDocument: %s\n", pCur -> title);
    			printf("Author: %s %s\n", pCur -> fname, pCur -> lname);
    		
    			for(i = 0; i < count + 1; i++){
    				if(pCur -> hits[i] != 0)
    					printf("%s(%d) ", search[i], pCur -> hits[i]);
    			}
    		
    			printf("\nScore: %d\n", pCur -> score);
    		}
    	
    		pCur -> score = 0;
    		pNew = pNew -> next;
    	}
    }
    Here's the input:

    Code:
    2
    Robin Jena
    Stock_market
    liquidity fiscal Quote debt funds price fiscal
    venture quote trailing accounts fiscal diluted Inventory 
    analyst inventory yield Stock inventory DOCUMENT_OVER
    William Boyd
    Heart
    nuclear cardio radiometry arthritis 
    heart patient ventricular patient treadmill wine 
    diagnosis yield analyst inventory yield yield 
    cardio analyst DOCUMENT_OVER
    Here's the output:

    Code:
    List of options: 
    	1. Load
    	2. Query
    	3. Quit
    
    Enter choice: 1
    Name the load file: test.txt
    
    Stock_market
    19 words
    Height 5
    liquidity quote(2) venture yield trailing stock price fiscal(3) funds inventory(3) debt diluted accounts analyst 
    
    Heart
    37 words
    Height 5
    nuclear radiometry ventricular wine yield(3) treadmill patient(2) cardio(2) heart inventory diagnosis arthritis analyst(2) 
    
    List of options: 
    	1. Load
    	2. Query
    	3. Quit
    
    Enter choice: 2
    Name the query file: query.txt
    
          0 [main] a 3768 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
      10683 [main] a 3768 stackdump: Dumping stack trace to a.exe.stackdump
    
     ----jGRASP cygwin wedge2: process died on signal 11.
     ----jGRASP: operation complete.
    Now I've figured out that it's crashing in the findhits() function. I've played around with it for a long time and still can't get it to work. Does anyone have any ideas of how I could change that function to get the program working?

  2. #2
    Registered User
    Join Date
    Apr 2004
    Posts
    173
    Just by looking at the findhits() function:

    Code:
    int findhits(struct tree_node *p, int i){
    	struct tree_node *pCur = p;	
    	
    	if(strcmp(pCur -> data, search[i]) == 0)
    		return(pCur -> count);
    		
    	if(strcmp(pCur -> data, search[i]) < 0)
    		findhits(pCur -> left, i);
    		
    	if(strcmp(pCur -> data, search[i]) > 0)
    		findhits(pCur -> right, i);
    }
    The obvious problem is when p becomes NULL. You have no code to check for that and what you did was simply dive in and derefence a NULL pointer which is a no-no. I could be wrong though since I just took a quick glance but it seems that the function would only work if the data actually was in the tree, otherwise it would eventually encounter a NULL and boom.

    So perhaps you could check the value of p before having the if statements, if p == NULL then return a value to indicate it couldn't be found.
    The cost of software maintenance increases with the square of the programmer's creativity.

  3. #3
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    An observation, you seem to be looking for "QUERY_OVER" in your query() function, but I don't see that in your data file.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  4. #4
    Registered User
    Join Date
    Feb 2005
    Posts
    26
    Ok, thanks for the help I got the program working. I know the code is probably poor and a jumbled mess but atleast it works. As for looking for "QUERY_OVER" I forgot to post that in my first post. That input file looks like:

    Code:
    heart yield patient QUERY_OVER
    I made these changes to the findhits() function:

    Code:
    /* Return the amount of hits */
    int findhits(struct tree_node *p, int i){
    	struct tree_node *pCur = p;	
    	
    	if(pCur != NULL){
    		if(strcmp(pCur -> data, search[i]) == 0)
    			return(pCur -> count);	
    		
    		else if(strcmp(pCur -> data, search[i]) < 0)
    			findhits(pCur -> left, i);
    		
    		else if(strcmp(pCur -> data, search[i]) > 0)
    			findhits(pCur -> right, i);
    	}
    }
    I also had to make some adjustments to finescore() and printresults(). I had a few crashes there but I was able to fix those easily. I can't believe I forgot to check for NULL, I had been coding for hours and started making lots of mistakes.

    Now that I've turned this in. Can anyone suggest a cleaner more effective way to code this using the binary search trees inside a linear link list? I can't help but to feel somehow that my code is ineffective. The tree wasn't suposed to be AVL for simplicities sake.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can someome help me with a program please?
    By WinterInChicago in forum C++ Programming
    Replies: 3
    Last Post: 09-21-2006, 10:58 PM
  2. need help program crashing
    By tunerfreak in forum C++ Programming
    Replies: 14
    Last Post: 05-22-2006, 11:29 AM
  3. Need help with my program...
    By Noah in forum C Programming
    Replies: 2
    Last Post: 03-11-2006, 07:49 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM