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(¤tLine);
}
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的函数。在此功能中,我使用另一个...