繁体   English   中英

valgrind 使用 getline 函数报告内存丢失

[英]valgrind report memory loss using getline function

我正在用 C 编写 grep 程序。我在 while 循环中使用 getline() 从流(文件或标准输入)中获取所有行。 这些行存储在我定义的名为 lineInText 的结构内的 char *lineText 缓冲区中。
不幸的是,即使我在循环结束时释放了这个 char *lineText,我仍然收到一个 valgrind 报告说使用 getline() 会丢失内存。
我究竟做错了什么?

编码:
line的结构体及其相关函数:

typedef struct lineInText
{
    char *lineText;
    int indexOfLine;
    int numOfBytesFromStartToHere;
    bool isMatchInLine;
    bool isMatchInLineFromA;
} lineInText;


void initializeCurrentLine(lineInText *currentLine)
{
    currentLine->lineText = NULL;
    currentLine->numOfBytesFromStartToHere=0;
    currentLine->isMatchInLineFromA = false;
    currentLine->isMatchInLine = false;
    currentLine->indexOfLine = 0;
}

void FillLineStruct(lineInText *currentLine, int lineIndex, int numOfBytes) {
    currentLine->indexOfLine = lineIndex;
    currentLine->isMatchInLine = false;
    currentLine ->isMatchInLineFromA = false;
    currentLine->numOfBytesFromStartToHere = numOfBytes;
}

void freeLine(lineInText **line)
{
    free((*line)->lineText);
    free(*line);
}

main() 和调用 getline() 的函数:

void receiveAndExecute(parsedCommandStruct *parsedCommand, FILE **stream)
{
    ssize_t lineSize = ZERO;
    lineInText *currentLine = NULL;
    int lineIndex = 1, counterForC = 0, linesAfterMatchCounter = 0, sumOfBytes = 0;
    currentLine = (lineInText *) malloc(sizeof(lineInText));
    initializeCurrentLine(currentLine);

    while (1)
    {
        readLine(stream, &lineSize, currentLine, lineIndex);
        FillLineStruct(currentLine, lineIndex, sumOfBytes);
        sumOfBytes = (int)lineSize + sumOfBytes;
        lineIndex++;
        if(lineSize<0)
            break;
        reportLineMatch(currentLine, *parsedCommand, &linesAfterMatchCounter);
        printLineToOutput(currentLine, parsedCommand, &counterForC, false);
    }
    printLineToOutput(currentLine, parsedCommand, &counterForC, true);
    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;
}

void readLine(FILE **stream, ssize_t *getLineResult, lineInText *currentLine,  int lineIndex) {
    ssize_t lineSize = ZERO;
    size_t lineBufSize = ZERO;
    lineSize = getline(&(currentLine->lineText), &lineBufSize, *stream);
    *getLineResult = lineSize;
}

瓦尔格林德报告:

valgrind --quiet --leak-check=yes ./my_grep bla bla | diff bla -==1878== 120 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1878==    at 0x402C17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==1878==    by 0x40A9FD7: getdelim (iogetdelim.c:62)
==1878==    by 0x40A6EB1: getline (getline.c:32)
==1878==    by 0x8048E79: readLine (in /home/user/Downloads/my_grep/my_grep)
==1878==    by 0x80493EF: receiveAndExecute (in /home/user/Downloads/my_grep/my_grep)
==1878==    by 0x804952A: main (in /home/user/Downloads/my_grep/my_grep)
==1878==

提前致谢

当您调用getlinelineBufSize的值为 0。这意味着该函数认为缓冲区的长度为 0 字节。 这对于第一次迭代是可以的,但是在随后的迭代中会导致存储在currentLine->lineText中的现有指针被抛出,从而导致内存泄漏。

您需要向结构中添加一个字段以跟踪缓冲区的当前大小并将其传递给getline

typedef struct lineInText
{
    char *lineText;
    int lineTextLen;    // keep track of the size of lineText
    int indexOfLine;
    int numOfBytesFromStartToHere;
    bool isMatchInLine;
    bool isMatchInLineFromA;
} lineInText;

void initializeCurrentLine(lineInText *currentLine)
{
    currentLine->lineText = NULL;
    currentLine->lineTextLen = 0;   // initialize buffer length to 0
    currentLine->numOfBytesFromStartToHere=0;
    currentLine->isMatchInLineFromA = false;
    currentLine->isMatchInLine = false;
    currentLine->indexOfLine = 0;
}

void readLine(FILE **stream, ssize_t *getLineResult, lineInText *currentLine,  int lineIndex) {
    ssize_t lineSize = ZERO;
    lineSize = getline(&(currentLine->lineText), &(currentLine->lineTextLen), *stream);
    *getLineResult = lineSize;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM