Thread: help stop crashing

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    6

    help stop crashing

    Hello. I making this program called jumble. what it does is take in letters given by the players and prints out all the permutation solutions to the word. I have plenty of comments on the code if anyone wants to have a look. it will run on the codeblocks complier but it will crashes almost immediately and i do not know why.can someone please help? thanks in advance

    Code:
    #include <math.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    
    /* the maximal lentgh of the user input allowed. */
    #define MAX_STRING_LENGTH 256
    /* the file name of the dictionary file. */
    #define DICTIONARY_FILENAME "dictionary.in"
    
    
    /* read in the dictorany text file, and create an in-memory dictitonary.
     * 2nd parameter is the number of words in the dictionary, read from the 1st line of the file;
     * the return points to the in-memory array of strings.
     */
    char** createDictionary(char* dictFileName, int* wordsCount);
    /* free up the space of the in-memory dictionary. */
    void freeDictionary(char** pDictionary, int wordsCount);
    
    
    /* search the dictionary (range from istart to iend) to decide whether the word exists or not: binary search.
     * if hit, return 1; otherwise 0.
     */
    int searchAword(char* pWord, char** pDictionary, int istart, int iend);
    
    
    /* swap two characters in a word. */
    void swapChar(char* pWord, int iPos1, int iPos2);
    
    
    /* try all the permutations of the pWord, of which the first nfix characters
     * are fixed in the original order and all the rest characters are arbitrarily permuted.
     * Thus, start by recursivePermuteLookup(word, 0): this will list all possible permutations,
     * especially for each permutation, lookup in dictionary to find whether it is hit or not.
     * The return of the function is the number of valid permutation.
     */
    int recursivePermuteLookup(FILE *ifOut, char* pWord, int nfix, char** pDictionary, int wordsCount, char* pOriginalWord);
    
    
    
    
    /* main function. */
    int main(){
        int wordsCount = 0;
        char** pDictionary = NULL;
        char userInput[MAX_STRING_LENGTH];
        char tempstore[MAX_STRING_LENGTH];
    
    
        /* create in-memory dictionary. */
        pDictionary = createDictionary(DICTIONARY_FILENAME, &wordsCount);
    
    
        //Read in test words.
        int cases, i;
        FILE *ifp, *ifOut;
        ifp = fopen ("dictionary.in", "r");
        ifOut = fopen("dictionary2.out", "w");
        fscanf (ifp, "%d", &cases);
        for (i = 0; i < cases; i++){
            fscanf (ifp, "%s", userInput);
            fprintf(ifOut, "Jumble #%d:\n", i+1);
            strlwr(userInput);    // lower case.
            strcpy(tempstore, userInput);   // keep the original word, for output purpose.
    
    
            int countHits = recursivePermuteLookup(ifOut, userInput, 0, pDictionary, wordsCount, tempstore);   // permute + lookup.
            if (countHits == 0){
                printf("Sorry, no permutations of %s form a word.\n", tempstore);   // print this statement if no hits.
            }
    
    
            fprintf(ifOut, "\n");
        }
    
    
        /* destroy the dictionary. */
        freeDictionary(pDictionary, wordsCount);
    
    
        printf("Thanks for using the Jumble Solver!\n");
    
    
        fclose(ifp);
        system("PAUSE");
        return 0;
    }
    
    
    
    
    char** createDictionary(char* dictFileName, int* wordsCount){
      char** pDictionary = NULL;
      FILE* pDictFile = fopen(dictFileName, "r");   // open file.
    
    
      if (pDictFile != NULL){
        /* read the 1st line, get to know how many words in the dictionary. */
        fscanf(pDictFile, "%d\n", wordsCount);
    
    
        /* create in-memory array, each entry points to one word. */
        pDictionary = (char **)malloc(*wordsCount * sizeof(char *));
    
    
        int vi = 0;
        int wordLength = 0;
        char word[MAX_STRING_LENGTH];
        for (vi = 0; vi < *wordsCount; vi++){
          fscanf(pDictFile, "%s\n", word);    // read in one word.
          wordLength = strlen(word) + 1;
          pDictionary[vi] = (char *)malloc(wordLength);   // create a block to hold the word.
          memset(pDictionary[vi], 0, wordLength);
          strcpy(pDictionary[vi], word);    // copy the word to the memory block.
          memset(word, 0, MAX_STRING_LENGTH);
        }
    
    
        fclose(pDictFile);    // close file.
      }
      return pDictionary;
    }
    
    
    
    
    void freeDictionary(char** pDictionary, int wordsCount){
      int vi = 0;
      for (vi = 0; vi < wordsCount; vi++){
        free(pDictionary[vi]);
        pDictionary[vi] = NULL;
      }
      free(pDictionary);
    }
    
    
    
    
    int searchAword(char* pWord, char** pDictionary, int istart, int iend){
      if (istart == iend){
        return ((strcmp(pWord, pDictionary[istart])) == 0);   // Only 1 word left, is it a hit...
      }
      else if (istart == (iend - 1)){
        /* 2 words left, check any hit... */
        return (((strcmp(pWord, pDictionary[istart])) == 0) || ((strcmp(pWord, pDictionary[iend])) == 0));
      }
      else{
        /* binary search: check the word in the middle to decide goto which branch (left/right). */
        int imiddle = (int)(floor((istart + iend) / 2));
        int compareResult = strcmp(pWord, pDictionary[imiddle]);
        if (compareResult == 0){
          /* the middle happens to be an exact match. */
          return 1;
        }
        else if (compareResult > 0){
          /* pWord is greater than the middle, goes to the right branch. */
          return searchAword(pWord, pDictionary, imiddle, iend);
        }
        else{
          /* pWord is smaller than the middle, goes to the left branch. */
          return searchAword(pWord, pDictionary, istart, imiddle);
        }
      }
    }
    
    
    
    
    void swapChar(char* pWord, int iPos1, int iPos2){
      char tempchar = pWord[iPos1];
      pWord[iPos1] = pWord[iPos2];
      pWord[iPos2] = tempchar;
    }
    
    
    
    
    int recursivePermuteLookup(FILE *ifOut, char* pWord, int nfix, char** pDictionary, int wordsCount, char* pOriginalWord){
      int countHits = 0;
    
    
      if (nfix == strlen(pWord)){
        int i........ = searchAword(pWord, pDictionary, 0, wordsCount - 1);
        if (i........ == 1){
          countHits++;
          fprintf(ifOut, "A permutation of %s that is a valid word is %s.\n", pOriginalWord, pWord);
        }
      }
      else{
        int vi = 0;
        /* from the next position, recursive/swap. */
        for (vi = nfix; vi < strlen(pWord); vi++){
          swapChar(pWord, nfix, vi);    // swap two characters.
          countHits = countHits + recursivePermuteLookup(ifOut, pWord, nfix + 1, pDictionary, wordsCount, pOriginalWord);    // recursive lookup.
          swapChar(pWord, vi, nfix);    // swap back.
        }
      }
    
    
      return countHits;
    }

  2. #2
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    1) At least it compiles without warnings (if you include <string.h> and fix that ......... junk towards the end).
    2) People will tell you to not cast the result of malloc.
    3) Do you check the return of fscanf? Ever? You've missed several fopen's too. Basically you're just not checking enough to make sure you're even opening these files and reading the data correctly, let alone acting on them.
    4) We don't have a copy of the file you read from.
    5) You don't free quite a lot of the things you malloc (Edit: I take that back - but you certainly memset local variables to zero after you've finished with them for no reason at all, and memset memory that you're about to strcpy into anyway).

    I didn't get past that point to actually look at the reason - someone else might be that kind - but the fact you don't bother to check to see if fscanf returned an error means that you could be acting on absolute junk from that point on, and that's where I lose interest.
    Last edited by ledow; 10-10-2012 at 08:03 AM. Reason: Correction

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    6
    for anyone else who wants to help i attached the text files to this post. I feel like i'm close to finishing this program but its a small problem that im missing and i can't figure it out. thanks very much.

    P.S: ledow thanks for the help (and when i mean help i meant number 3 of your insults) and hopefully in the future you wake up on the right side of the bread.
    Attached Files Attached Files

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    (Silly question, but) Did you edit this for your post?
    Code:
    int i........ = searchAword(pWord, pDictionary, 0, wordsCount - 1);
        if (i........ == 1){
    I'm guessing one of your files is not opening in your main.
    Fact - Beethoven wrote his first symphony in C

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You need to post more details about the crash you're observing.

    Code:
    << massive snip >>
    Sorry, no permutations of zoom form a word.
    Sorry, no permutations of zooming form a word.
    Thanks for using the Jumble Solver!
    ==3868== 
    ==3868== HEAP SUMMARY:
    ==3868==     in use at exit: 568 bytes in 1 blocks
    ==3868==   total heap usage: 10,004 allocs, 10,003 frees, 150,887 bytes allocated
    ==3868== 
    ==3868== LEAK SUMMARY:
    ==3868==    definitely lost: 0 bytes in 0 blocks
    ==3868==    indirectly lost: 0 bytes in 0 blocks
    ==3868==      possibly lost: 0 bytes in 0 blocks
    ==3868==    still reachable: 568 bytes in 1 blocks
    ==3868==         suppressed: 0 bytes in 0 blocks
    ==3868== Rerun with --leak-check=full to see details of leaked memory
    ==3868== 
    ==3868== For counts of detected and suppressed errors, rerun with: -v
    ==3868== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
    Apart from a single memory leak, valgrind reports no issues.

    The obvious crash points (not checking your files were opened) have already been noted.
    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.

  6. #6
    Registered User
    Join Date
    Apr 2012
    Posts
    6
    ok after numerous tries i got it to run but now i realize i need a statement for a menu. something that allows me to say something like if x=1 enter word else thanks for playing jumble program. i tried but i feel like im missing something. im sure its supposed to go in main. any help would be appreciated. thanks in advance

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by gokutrnks View Post
    ok after numerous tries i got it to run but now i realize i need a statement for a menu. something that allows me to say something like if x=1 enter word else thanks for playing jumble program. i tried but i feel like im missing something. im sure its supposed to go in main. any help would be appreciated. thanks in advance
    These kinds of games usually use a large do while or while loop, around a series of if statements or a switch statement, looping around until the user enters a number or letter that ends the loop.

    Code:
    do {
        //print up the valid choices here
       //get the user's choice, here
       switch(choice) {
          case 1:
          //do stuff, usually by calling other functions
          //break;
         case 2:
            //handle this choice, again generally by calling other functions
            //break;
         case 3: break;
         default:
             //print up message to user to re-enter his choice.
      }
    
    }while(choice != 3);
    Something like that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. crashing
    By Tool in forum C++ Programming
    Replies: 4
    Last Post: 07-11-2010, 01:23 PM
  2. Crashing
    By SanderK in forum C++ Programming
    Replies: 1
    Last Post: 03-24-2009, 05:41 PM
  3. Stop button doesnt stop a function (using PostMessage)
    By scwizzo in forum Windows Programming
    Replies: 7
    Last Post: 03-07-2008, 07:54 PM
  4. Crashing...
    By webren in forum C++ Programming
    Replies: 3
    Last Post: 04-17-2005, 01:09 AM
  5. How do I stop cin from crashing my prog
    By Panopticon in forum C++ Programming
    Replies: 10
    Last Post: 12-13-2004, 03:41 PM