Thread: bus error in code

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    31

    bus error in code

    I can't figure out why I'm getting a bus error here..

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void RecursivePermute(char jumble[], int k, char * words[], int size_of_dictionary);
    void ExchangeCharacters(char jumble[], int i, int j);
    int inDictionary(char jumble[], char * words[], int size_of_dictionary);
    
    // Pre-condition: 'words' is a valid C String, and 'k' is non-negative and
    //                less than or equal to the length of words.
    // Post-condition: All of the permutations of words with the first 'k'
    //                 characters fixed in their original positions are
    //                 printed. Namely, if n is the length of words, then
    //                 (n-k)! permutations are printed.
    void RecursivePermute(char jumble[], int k, char * words[], int size_of_dictionary) {
    	
    	int i, j;
    	
    	// Base-case: Since all letters are fixed, we can ONLY print
    	// what's stored in str.
    	if (k == strlen(jumble)) {
    		if(inDictionary(jumble, words, size_of_dictionary) == 1) {
    			printf("A permutation of %s that is a valid word is .\n", jumble);
    		}
    	}
    	else {
    		
    		// Loop through each possible starting letter for index k,
    		// the first index for which we have a choice.
    		for (j=k; j<strlen(jumble); j++) {
    			
    			// Place the character stored in index j in location k.
    			ExchangeCharacters(jumble, k, j);
    			
    			// Print out all of the permutations with that character
    			// just chosen above fixed. 
    			RecursivePermute(jumble, k+1, words, size_of_dictionary);
    			
    			// Put the original character that used to be there back
    			// in its place.
    			ExchangeCharacters(jumble, j, k);
    		}
    	}
    }
    
    // Pre-condition: words is a valid C String and i and j are valid indexes
    //                to that string.
    // Post-condition: The characters at index i and j will be swapped in
    //                 str.
    void ExchangeCharacters(char jumble[], int i, int j) {
    	
        char temp = jumble[i];
        jumble[i] = jumble[j];
        jumble[j] = temp;
    }
    
    int inDictionary(char jumble[], char * words[], int size_of_dictionary) {
    
    	int left=0, mid, right=size_of_dictionary-1;
    	
    	while(left <= right) {
    		mid = (left + right)/2;
    		if((strcmp(jumble, words[mid])) == 0) {
    			return 1;
    		}
    		if((strcmp(jumble, words[mid])) < 0) {
    			left = mid + 1;
    		}
    		if((strcmp(jumble, words[mid])) > 0) {
    			right = mid - 1;
    		}
    	}
    	return 0;
    
    }
    It seems like the array named "words" is not being read into function inDictionary properly, and I know the program experiences the bus error at the moment it tries to compute the strcmp function. I've had no luck troubleshooting though..help anyone??
    Last edited by 3MGFX; 02-04-2009 at 09:24 PM. Reason: Edited out irrelevant portion of code

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You should have posted the whole thing (which you did, before your edit).
    All the real horrors are in the bit you removed.
    Code:
    int main() {
    
    FILE * ifp;
    int size_of_dictionary, num_of_jumbled_words;
    int i, j;
    char ** words;
    char jumble;
    
    ifp = fopen("dictionary.in", "r");
    if(ifp == NULL) {
    printf("The file that you are trying to access is invalid.\n");
    }
    else {
    fscanf(ifp, "%d", &size_of_dictionary);
    }
    
    for(i=0; i<size_of_dictionary; i++) {
    words = (char **)malloc(size_of_dictionary*sizeof(char*));
    // Bad bad, you're allocating your outer array EVERY time
    // All except the last pointer is gonna be junk
    
    if(words == NULL) {
    printf("Sorry, there is not enough available memory to be allocated.\n");
    break;
    }
    words[i] = (char*)malloc(sizeof(char)*MAX_SIZE);
    fscanf(ifp, "%s", &words[i]);
    }
    fclose(ifp);
    
    ifp = fopen("jumble.txt", "r");
    fscanf(ifp, "%d", &num_of_jumbled_words);
    
    for(j=1; j<=num_of_jumbled_words; j++) {
    printf("Jumble #%d:\n", j);
    fscanf(ifp, "%s", &jumble);
    // jumble is a char, you're reading a string
    
    RecursivePermute(&jumble, 0, words, size_of_dictionary);
    }
    
    fclose(ifp);
    free(words);
    return 0;
    
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    I hate it when people say the bug is in this bit of code.
    If they knew where the bug was, they would not need someone to find it for them!!

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    31
    ^^You're absolutely right, man. But if you read the bottom of my post, you would see that I was trying to explain the way I was approaching the problem..and maybe someone more experienced could show me a different way of looking at it so that way I could actually learn something..as oppose to someone just showing me where the errors were..

    I'm getting a "segmentation fault" error message now..and I believe that has something to do with the manner in which I'm allocating my memory. But I don't understand why that would change by just moving it out of the previous for loop as instructed.

    I turned in the assignment already..but I would love to get this working so that I may play around with it and optimize it; that would be good practice in the long run. I'll repost my entire algorithm as well.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_SIZE 30
    
    void RecursivePermute(char jumble[], int k, char * words[], int size_of_dictionary);
    void ExchangeCharacters(char jumble[], int i, int j);
    int inDictionary(char jumble[], char * words[], int size_of_dictionary);
    
    int main() {
    	
    	FILE * ifp;
    	int size_of_dictionary, num_of_jumbled_words;
    	int i, j;
    	char ** words;
    	char jumble[MAX_SIZE];
    	
    	ifp = fopen("dictionary.in", "r");
    	if(ifp == NULL) {
    		printf("The file that you are trying to access is invalid.\n");
    	}
    	else {
    		fscanf(ifp, "%d", &size_of_dictionary);
    	}
    	
    	words = (char **)malloc(size_of_dictionary*sizeof(char*));
    	for(i=0; i<size_of_dictionary; i++) {
    		if(words == NULL) {
    			printf("Sorry, there is not enough available memory to be allocated.\n");
    			break;
    		}
    		words[i] = (char*)malloc(sizeof(char)*MAX_SIZE);
    		fscanf(ifp, "%s", &words[i]);
    	}
    	fclose(ifp);
    	
    	ifp = fopen("jumble.txt", "r");
    	fscanf(ifp, "%d", &num_of_jumbled_words);
    	
    	for(j=1; j<=num_of_jumbled_words; j++) {
    		printf("Jumble #%d:\n", j);
    		fscanf(ifp, "%s", &jumble);
    		RecursivePermute(jumble, 0, words, size_of_dictionary);
    	}
    	
    	fclose(ifp);
    	free(words);
    	return 0;
    	
    }
    
    // Pre-condition: 'words' is a valid C String, and 'k' is non-negative and
    //                less than or equal to the length of words.
    // Post-condition: All of the permutations of words with the first 'k'
    //                 characters fixed in their original positions are
    //                 printed. Namely, if n is the length of words, then
    //                 (n-k)! permutations are printed.
    void RecursivePermute(char jumble[], int k, char * words[], int size_of_dictionary) {
    	
    	int i, j;
    	
    	// Base-case: Since all letters are fixed, we can ONLY print
    	// what's stored in str.
    	if (k == strlen(jumble)) {
    		if(inDictionary(jumble, words, size_of_dictionary) == 1) {
    			printf("A permutation of %s that is a valid word is .\n", jumble, words[inDictionary(jumble, words, size_of_dictionary)]);
    		}
    	}
    	else {
    		
    		// Loop through each possible starting letter for index k,
    		// the first index for which we have a choice.
    		for (j=k; j<strlen(jumble); j++) {
    			
    			// Place the character stored in index j in location k.
    			ExchangeCharacters(jumble, k, j);
    			
    			// Print out all of the permutations with that character
    			// just chosen above fixed. 
    			RecursivePermute(jumble, k+1, words, size_of_dictionary);
    			
    			// Put the original character that used to be there back
    			// in its place.
    			ExchangeCharacters(jumble, j, k);
    		}
    	}
    }
    
    // Pre-condition: words is a valid C String and i and j are valid indexes
    //                to that string.
    // Post-condition: The characters at index i and j will be swapped in
    //                 str.
    void ExchangeCharacters(char jumble[], int i, int j) {
    	
        char temp = jumble[i];
        jumble[i] = jumble[j];
        jumble[j] = temp;
    }
    
    int inDictionary(char jumble[], char * words[], int size_of_dictionary) {
    
    	int left=0, mid, right=size_of_dictionary-1;
    	
    	while(left <= right) {
    		mid = (left + right)/2;
    		if((strcmp(jumble, words[mid])) == 0) {
    			return mid;
    		}
    		if((strcmp(jumble, words[mid])) < 0) {
    			left = mid + 1;
    		}
    		if((strcmp(jumble, words[mid])) > 0) {
    			right = mid - 1;
    		}
    	}
    	return 0;
    
    }

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Your approach sucks - happy now?
    How many times do you call strlen(jumble).

    > But I don't understand why that would change by just moving it out of the previous for loop as instructed.
    You don't? It's worse than I thought.

    Can you figure out why
    if(words == NULL)
    should be outside the loop as well?

    > words[i] = (char*)malloc(sizeof(char)*MAX_SIZE);
    Or why you SHOULD check this for NULL

    > ifp = fopen("jumble.txt", "r");
    And this for NULL as well.

    > free(words);
    You should free each words[i] before this.

    > But if you read the bottom of my post
    But if you read the top, the story is different.

    > if(inDictionary(jumble, words, size_of_dictionary) == 1)
    Strange, the function returns the INDEX of where the string is found.
    Being an index, zero is also a valid result, AND is also your "not found" result as well.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Enforcing Machine Code Restrictions?
    By SMurf in forum Tech Board
    Replies: 21
    Last Post: 03-30-2009, 07:34 AM
  2. Obfuscated Code Contest: The Results
    By Stack Overflow in forum Contests Board
    Replies: 29
    Last Post: 02-18-2005, 05:39 PM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. Replies: 0
    Last Post: 02-21-2002, 06:05 PM