valgrind:条件跳转或移动取决于使用strlen()strncat()的未初始化值>> [

问题描述 投票:0回答:1
我正在用C语言编写一个grep程序。为了确定是否应将收到的当前行打印到屏幕上,我使用了一个名为

reportLineMatchRec

的函数。在此函数中,我使用另一个名为updateConExpWithStr2的函数来解析reportLineMatchRec()中使用的字符串之一。不幸的是,即使我初始化了所有值,当使用strlen()和strncat()时,我仍然收到valgrind错误,该函数内部使用了未初始化的值。更新:我更新了函数updateConExpWithStr1()updateConExpWithStr2(),所以gcc警告消失了,现在我得到了一个valgrind错误(也在下面更新)。我将其添加到valgrind check --track-origins = yes参数中,该参数指出初始化问题的源位于commandParser模块(在下面添加)中的fillRoundBrackets()中的malloc中。我仍然无法解决问题。代码:

结构:

typedef enum {REGULAR, POINT, ROUND_BRACKETS, BRACKETS} partClassifier; union expressionPartInfo { char xy[2]; char *str1OrStr2; char regularChar; }expressionPartInfo; typedef struct partInExpression { union expressionPartInfo expressionPartInfo ; partClassifier partClassifier; } partInExpression; typedef struct parsedCommandStruct { char *expressionToSearch; char *origExpressionToSearch; char *concatenatedExpression; int lengthOfOrigExpression; int numOfExpressionParts; bool a; int aNum; bool b; bool c; bool i; bool n; bool v; bool x; bool E; struct partInExpression *arrayOfExpressionParts; } parsedCommandStruct;

更新过的matchInLine.c相关功能:

void updateConExpWithStr1(parsedCommandStruct *parsedCommand, char **endOfString, int partIndex, char **orPtr, int *str1size,char **orPtrcopy){ char *copyStr1OrStr2 = malloc(parsedCommand->lengthOfOrigExpression+1); strcpy(copyStr1OrStr2, parsedCommand->arrayOfExpressionParts[partIndex].expressionPartInfo.str1OrStr2); *endOfString = parsedCommand->concatenatedExpression+strlen(parsedCommand->concatenatedExpression); *orPtr = strstr(parsedCommand->arrayOfExpressionParts[partIndex].expressionPartInfo.str1OrStr2, "|"); *orPtrcopy=(*orPtr)+1; **orPtr = '\0'; *str1size = strlen(parsedCommand->arrayOfExpressionParts[partIndex].expressionPartInfo.str1OrStr2); strcat(parsedCommand->concatenatedExpression, parsedCommand->arrayOfExpressionParts[partIndex]. expressionPartInfo.str1OrStr2); strcpy(parsedCommand->arrayOfExpressionParts[partIndex].expressionPartInfo.str1OrStr2, copyStr1OrStr2); free(copyStr1OrStr2); } void updateConExpWithStr2(parsedCommandStruct *parsedCommand, int partIndex, char **orPtr, int const*str1size, char **endOfString, char **orPtrcopy){ int str2size=0; **endOfString = '\0'; str2size = strlen(*orPtrcopy); strncat(parsedCommand->concatenatedExpression, *orPtrcopy, str2size); } void reportLineMatchRecE(int partIndex, lineInText *currentLineToCheck, parsedCommandStruct *parsedCommand, int *linesAfterMatchCounterPtr, int *prevLinesCounter, int *matchFlag){ int j=0; char *orPtr = NULL; int str1size = 0; char *endOfString = NULL; char *orPtrcopy = NULL; while(partIndex < parsedCommand->numOfExpressionParts){ if(parsedCommand->arrayOfExpressionParts[partIndex].partClassifier == REGULAR) { updateConExpWithRegChr(parsedCommand, &partIndex); } else if (parsedCommand->arrayOfExpressionParts[partIndex].partClassifier == POINT){ for (j = ASCII_LOWEST_CHAR; j < ASCII_HIGHEST_CHAR+1; j++) { updateConExpWithChr(j, parsedCommand, &endOfString); reportLineMatchRec(partIndex+1, currentLineToCheck, parsedCommand, linesAfterMatchCounterPtr, prevLinesCounter, matchFlag); *endOfString='\0'; } return; } else if(parsedCommand->arrayOfExpressionParts[partIndex].partClassifier == BRACKETS){ for (j = parsedCommand->arrayOfExpressionParts[partIndex].expressionPartInfo.xy[0]; j < parsedCommand->arrayOfExpressionParts[partIndex].expressionPartInfo.xy[1]+1; j++) { updateConExpWithChr(j, parsedCommand, &endOfString); reportLineMatchRec(partIndex+1, currentLineToCheck, parsedCommand, linesAfterMatchCounterPtr, prevLinesCounter, matchFlag); *endOfString='\0'; } return; } else if(parsedCommand->arrayOfExpressionParts[partIndex].partClassifier == ROUND_BRACKETS){ updateConExpWithStr1(parsedCommand, &endOfString, partIndex, &orPtr ,&str1size, &orPtrcopy); reportLineMatchRec(partIndex+1, currentLineToCheck, parsedCommand, linesAfterMatchCounterPtr, prevLinesCounter, matchFlag); updateConExpWithStr2(parsedCommand, partIndex, &orPtr, &str1size, &endOfString, &orPtrcopy); reportLineMatchRec(partIndex+1, currentLineToCheck, parsedCommand, linesAfterMatchCounterPtr, prevLinesCounter, matchFlag); return; } } if(partIndex == parsedCommand->numOfExpressionParts){ strcpy(parsedCommand->expressionToSearch, parsedCommand->concatenatedExpression); reportLineMatch(currentLineToCheck, *parsedCommand, linesAfterMatchCounterPtr, prevLinesCounter, matchFlag); return; } }

commandParser.c相关函数:

int fillRoundBrackets(parsedCommandStruct *parsedCommand, int indexOfParts, char *str1OrStr2){ parsedCommand->arrayOfExpressionParts[indexOfParts].partClassifier = ROUND_BRACKETS; char *placeOfClosingBracket = strstr(str1OrStr2, ")"); int str12Size = placeOfClosingBracket-str1OrStr2 - 1; parsedCommand->arrayOfExpressionParts[indexOfParts].expressionPartInfo.str1OrStr2 = NULL; parsedCommand->arrayOfExpressionParts[indexOfParts].expressionPartInfo.str1OrStr2 = malloc(200);//str12Size+1); strncpy(parsedCommand->arrayOfExpressionParts[indexOfParts].expressionPartInfo.str1OrStr2, str1OrStr2+1, str12Size); return str12Size+1; } void buildArrayOfExpressionParts(parsedCommandStruct *parsedCommand){ int numOfParts = computeNumOfParts(parsedCommand->expressionToSearch); int i=0, indexOfParts=0; parsedCommand->arrayOfExpressionParts = NULL; parsedCommand->arrayOfExpressionParts = malloc(numOfParts * sizeof(partInExpression)); for(i=0; i<(int)strlen(parsedCommand->expressionToSearch); i++) { if(parsedCommand->expressionToSearch[i] == '.') { parsedCommand->arrayOfExpressionParts[indexOfParts].partClassifier = POINT; } else if(parsedCommand->expressionToSearch[i] == '[') { fillBrackets(parsedCommand, indexOfParts, parsedCommand->expressionToSearch[i+1], parsedCommand->expressionToSearch[i+3]); i=i+4; } else if(parsedCommand->expressionToSearch[i] == '(') { parsedCommand->arrayOfExpressionParts[indexOfParts].expressionPartInfo.str1OrStr2 = NULL; i = i + fillRoundBrackets(parsedCommand, indexOfParts, parsedCommand->expressionToSearch + i); } else if(parsedCommand->expressionToSearch[i] == '\\') { fillRegularChar(parsedCommand, indexOfParts, parsedCommand->expressionToSearch[i+1]); i=i+1; } else { fillRegularChar(parsedCommand, indexOfParts, parsedCommand->expressionToSearch[i]); } indexOfParts++; } } void createAndFillCommand(int argc, char *argv[], parsedCommandStruct **parsedCommand) { int indexOfExpressionArg = INITIALIZED_VALUE; indexOfExpressionArg = searchExpressionArgumentIndex(argc, argv); *parsedCommand = (parsedCommandStruct *) malloc(sizeof(struct parsedCommandStruct)); initializeCommandArgs(parsedCommand); (*parsedCommand)->expressionToSearch = (char *)malloc(strlen(argv[indexOfExpressionArg])+1); strcpy((*parsedCommand)->expressionToSearch, argv[indexOfExpressionArg]); (*parsedCommand)->origExpressionToSearch = (char *)malloc(strlen(argv[indexOfExpressionArg])+1); strcpy((*parsedCommand)->origExpressionToSearch, argv[indexOfExpressionArg]); (*parsedCommand)->lengthOfOrigExpression = strlen((*parsedCommand)->expressionToSearch); // delete? (*parsedCommand)->numOfExpressionParts = computeNumOfParts((*parsedCommand)->expressionToSearch); updateArgumentsOfCommandStruct(argc, argv, *parsedCommand); if((*parsedCommand)->E){ buildArrayOfExpressionParts(*parsedCommand); (*parsedCommand)->concatenatedExpression = (char *)malloc(strlen(argv[indexOfExpressionArg])+1); strcpy((*parsedCommand)->concatenatedExpression, ""); } }

main.c:

void receiveAndExecute(parsedCommandStruct *parsedCommand, FILE **stream) { ssize_t lineSize = INITIALIZED_VALUE; int matchFlag = 0; lineInText *currentLine = NULL; int lineIndex = FIRST_LINE_INDEX, counterForC = INITIALIZED_VALUE, linesAfterMatchCounter = INITIALIZED_VALUE, sumOfBytes = INITIALIZED_VALUE, prevLinesCounter = INITIALIZED_VALUE; currentLine = malloc(sizeof *currentLine); initializeCurrentLine(currentLine); while (1) { readLine(stream, &lineSize, currentLine); FillLineStruct(currentLine, lineIndex, sumOfBytes); sumOfBytes = (int)lineSize + sumOfBytes; lineIndex++; initializeConcatinateExp(parsedCommand); if(lineSize<0) break; reportLineMatchRec(0, currentLine, parsedCommand, &linesAfterMatchCounter, &prevLinesCounter, &matchFlag); printLineToOutput(currentLine, parsedCommand, &counterForC, false, &linesAfterMatchCounter, &prevLinesCounter, &matchFlag); } printLineToOutput(currentLine, parsedCommand, &counterForC, true, NULL, NULL, NULL); freeLine(&currentLine); } int main(int argc, char* argv[]) { parsedCommandStruct *parsedCommand = NULL; FILE *filePtr = NULL; bool useFile = false; useFile = isUsingFile(argc, argv); createAndFillCommand(argc, argv, &parsedCommand); if (useFile) { filePtr = openFile(argv[argc-1]); receiveAndExecute(parsedCommand, &filePtr); fclose(filePtr); } else { receiveAndExecute(parsedCommand, &stdin); } freeParsedCommandStruct(parsedCommand); free(parsedCommand); return 0; }

更新的valgrind报告

==7832== Conditional jump or move depends on uninitialised value(s) ==7832== at 0x4C2E1EB: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7832== by 0x401BF7: updateConExpWithStr1 (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== by 0x401F48: reportLineMatchRecE (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== by 0x4020A4: reportLineMatchRec (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== by 0x402280: receiveAndExecute (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== by 0x402377: main (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== Uninitialised value was created by a heap allocation ==7832== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7832== by 0x40108C: fillRoundBrackets (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== by 0x401218: buildArrayOfExpressionParts (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== by 0x40142D: createAndFillCommand (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832== by 0x40233B: main (in /specific/a/home/cc/students/csguests/nadavbarkol/c_lab/ex2/my_grep) ==7832==

我正在用C语言编写一个grep程序。为了确定是否应将收到的当前行打印到屏幕上,我使用了一个称为reportLineMatchRec的函数。在此功能中,我使用另一个...
c initialization valgrind strlen
1个回答
1
投票
将其从评论移至答案。
© www.soinside.com 2019 - 2024. All rights reserved.