首页 > 解决方案 > 将读取的字符串与一组随机字母进行比较的程序将在至少七个字母之前找到匹配项

问题描述

我目前正在做一个项目,由于最近的封锁,我无法与我的导师会面寻求帮助,所以我来找你。我的程序应该通过检查提供的 Linux 字典来检查随机生成的一组字母中的哪些单词。不幸的是,该程序似乎不会产生匹配,直到它开始搜索 7 个或更多字母然后崩溃说“realloc: invalid next size 0x0000000002473270”。我曾尝试使用 valgrind,但我还没有学会它,所以它提供的所有信息都非常压倒性。这是代码,我知道它与我的指针有关,但请帮忙!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char dicNames[6][31] = {"american-english","cracklib-small","words@","british-english","README.select-wordlist","words.pre-dictionaries-common@"};

int main(int argCount,char *userIn[]){
    int i,j,k=0,l,numLetters,runTimes,count3Switch;
    char lSwitch[] = "-l";
    char tSwitch[] = "-t";
    char dicfilename[46] = "/usr/share/dict/";
    char **matchWords;
    char *nextWord;
    char *userLetters;
    FILE *dicFile;
    FILE *outputFile;

    if(argCount > 4){printf("Error. Too many inputs.\n\n"); return 1;}//checks if the user inputted too many arguments
    if(argCount > 1){//checks if user inputted a valid dictionary name
        for(j=1;j<argCount;j++){
            for(i = 0;i<5;++i){
                if(strcmp(dicNames[i],userIn[j]) == 0) break;
                if(j == (argCount-1) && i == 4){printf("Error. Invalid Dictionary.\n\n"); return 1;}
            }
            if(strcmp(dicNames[i],userIn[j]) == 0) {strcat(dicfilename,userIn[j]); break;}
        }
    }
    if(argCount > 2){//checks if the optional third argument is valid
        for(j=1;j<argCount;j++){
            sscanf(userIn[j],"%*c%*c%d",&numLetters);
            sscanf(userIn[j],"%*c%*c%d",&runTimes);
                if(memcmp((char *)userIn[j],(char *)lSwitch,2) == 0 && numLetters <= 99 && numLetters >= 1){count3Switch = 1; j = 5; break;}
                if(memcmp((char *)userIn[j],(char *)tSwitch,2) == 0 && runTimes <= 999 && runTimes >= 1){count3Switch = 2; j = 5; break;}
            if(j == (argCount - 1)) {printf("Error. Invalid Input for 3rd Argument\n\n"); return 1;}
        }
    }
    if(argCount > 3){//checks if the optional fourth argument is valid
        for(j=1;j<argCount;j++){
            for(i=1;i<argCount;i++){
                sscanf(userIn[j],"%*c%*c%d",&numLetters);
                sscanf(userIn[i],"%*c%*c%d",&runTimes);
                if(memcmp((char *)userIn[j],(char *)lSwitch,2) == 0 && numLetters <= 99 && numLetters >= 1) 
                    if(memcmp((char *)userIn[i],(char *)tSwitch,2) == 0 && runTimes <= 999 && runTimes >= 1){
                        j = 5;
                        break;
                    }
            }
        }
        if(j == (argCount - 1)) {printf("Error. Invalid Input for 4th Argument\n\n"); return 1;}    
    }

/******************************************************************************************************/
//The above is solely command line argument validation. 
//It returns the number of runtimes as runTimes and letters as numLetters and the place of the dictionary as dicNum

    dicFile = fopen(dicfilename,"r");
    if(dicFile == NULL){fprintf(stderr,"Failed to open dictionary file\n"); return 1;}
    else{fprintf(stderr,"\nDictionary file opened successfully\n");}

/******************************************************************************************************/
//The above opens the dictionary and so now the program is ready to actually run
//57 lines of code and not a single thing has been done yet lol.

    if(argCount < 3){//provides the runTimes and numLetters is user does not specify
        runTimes = rand() % 1000;
        numLetters = rand() % 100;
    }
    if(argCount == 3){//generates whatever of the two inputs the user did not provide
        if(count3Switch == 1) runTimes = rand() % 1000;
        if(count3Switch == 2) numLetters = rand() % 100;
    }

/******************************************************************************************************/
//The above handles randomization in case the user does not specify runtimes and number of letters

    for(i=1;i<=runTimes;k=0,i++){
        for(j=0,userLetters = malloc(numLetters*sizeof(char));j<numLetters;j++){//randomly generates the users letters
            userLetters[j] = (rand() % 26) + 65;//makes the users letter all uppercase
        }
        printf("\nRun #%d\nUser Letters are %s\n\n",i,userLetters);

        matchWords = (char **)calloc(10,sizeof(char *));//allocation for the starting values of the 2-D array to store found words
        matchWords[k] = (char *)calloc(numLetters+1,sizeof(char));

        for(j=1;j<=numLetters;j++){
            printf("Words that are Size of %d:\n\n",j);

            while(feof(dicFile) == 0){
                nextWord = (char *)calloc(numLetters+1,sizeof(char));//allocates the space for the next word being read in from the dictionary
                fgets(nextWord,sizeof(nextWord),dicFile);//gets the next word from the dictionary

                for(l=0;l<strlen(nextWord);l++){//adjusts all letters to capital from dicationary
                    if(nextWord[l]>90) nextWord[l] -= 32;
                }

                if(strlen(nextWord) == j){//a limiter applied to search for words based on size of words first.
                    if(strspn(nextWord,userLetters) == strlen(nextWord)){//checks if the word on this line of the dictionary can be made from the user's letters
                        fprintf(stdout,"%s\n",nextWord);
                        strcpy(matchWords[k],nextWord);//copies the valid word to the 2-D of matched values
                        k++;
                        matchWords = (char **) realloc(matchWords,sizeof(matchWords)+sizeof(char *));//memory reallocation for next word address
                        matchWords[k] = (char *) calloc(numLetters+1,sizeof(char));//memory allocation for new word added to array.
                    }
                }
                free(nextWord);//frees next word so that it can be recycled for the next line of dictionary
            }
            rewind(dicFile);//resets the dictionary back to it's start
        }
    }   
    return 0;
}
==31588== Memcheck, a memory error detector
==31588== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==31588== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==31588== Command: ./a.out american-english -l8 -t5
==31588==

Dictionary file opened successfully

Run #1
==31588== Invalid read of size 1
==31588==    at 0x4E82943: vfprintf (vfprintf.c:1661)
==31588==    by 0x4E8B3D8: printf (printf.c:33)
==31588==    by 0x401211: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==  Address 0x52002c8 is 0 bytes after a block of size 8 alloc'd
==31588==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linu        x.so)
==31588==    by 0x4011AB: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==
User Letters are NWLRBBMQ

Words that are Size of 1:

==31588== Invalid read of size 1
==31588==    at 0x4C32234: strspn (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linu        x.so)
==31588==    by 0x401332: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==  Address 0x52002c8 is 0 bytes after a block of size 8 alloc'd
==31588==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linu        x.so)
==31588==    by 0x4011AB: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==
Words that are Size of 2:

Words that are Size of 3:

Words that are Size of 4:

Words that are Size of 5:

Words that are Size of 6:

Words that are Size of 7:

Words that are Size of 8:


Run #2
User Letters are BHCDARZO

Words that are Size of 1:

Words that are Size of 2:

Words that are Size of 3:

Words that are Size of 4:

Words that are Size of 5:

Words that are Size of 6:

Words that are Size of 7:

BARABBA
BARBADO
==31588== Invalid write of size 8
==31588==    at 0x4013D4: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==  Address 0x67f3240 is 0 bytes after a block of size 16 alloc'd
==31588==    at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-lin        ux.so)
==31588==    by 0x4013A2: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==
BARBADO
==31588== Invalid read of size 8
==31588==    at 0x40137C: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==  Address 0x67f3240 is 0 bytes after a block of size 16 alloc'd
==31588==    at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-lin        ux.so)
==31588==    by 0x4013A2: main (in /users/ctroche/ECE2220/Project5/a.out)
==31588==
BARBARA
BARBARA
BARBARO
BARBARO
BOCCACC
BRADDOC
BRADDOC
CARDOZO
CARDOZO
CHARBRA
CHARBRA
COCHABA
CORDOBA

valgrind: m_mallocfree.c:304 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 109301296, hi = 0.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.


host stacktrace:
==31588==    at 0x3805DB16: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==31588==    by 0x3805DC24: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==31588==    by 0x3805DDA6: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==31588==    by 0x3806B092: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==31588==    by 0x3802CCA4: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==31588==    by 0x3802D007: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==31588==    by 0x380AEE81: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==31588==    by 0x380BDCBC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==31588==    at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linu        x.so)
==31588==    by 0x401291: main (in /users/ctroche/ECE2220/Project5/a.out)


Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

标签: cpointers

解决方案


推荐阅读