c - 将读取的字符串与一组随机字母进行比较的程序将在至少七个字母之前找到匹配项
问题描述
我目前正在做一个项目,由于最近的封锁,我无法与我的导师会面寻求帮助,所以我来找你。我的程序应该通过检查提供的 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.
解决方案
推荐阅读
- algorithm - 无向图 | 强盗能到达神奇的出口还是警察能抓住他们?
- postgresql - 无法删除表用户 - “用户”处或附近的语法错误 - 未知原因
- bash - bash 中的猜数游戏
- python - PHP:我可以将函数存储在类对象中并将值传递给它以供函数解释。Python可以做到,但是PHP可以吗?
- c# - ASP.Core 将 serviceprovider 传递给自定义 AuthorizeAttribute 的构造函数
- ios - 如何同时迭代 NSManagedObject 项的集合以提高性能?
- python - 从另一个 file.py 更新二维列表 - Python
- ios - SwiftUI - 从 UITableView (UIViewRepresentable) 导航到 View
- python - 关闭弹出窗口 Python Selenium
- javascript - 传单中的 Geoserver WMTS 服务不显示图块,列超出范围