Valgrind内存释放

时间:2013-12-06 14:27:04

标签: c malloc free valgrind memory-management

我一直在做一个学校项目,我似乎没有正确释放所有内存。我不知道我错过了哪里使用free

我的代码看起来像这样

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

#define MAXFILENAME 20

typedef struct tNode{
        int Deg;
        int Val;
        int* Neigh;
} *tNodePtr;

typedef struct tGraph{
        int Num;
        tNodePtr* Nodes;
} *tGraphPtr;


void GInit(tGraphPtr G, const char *FNum)
{
        char FileName[MAXFILENAME];
        char *FileNamePrefix = "Graph";
        char *FileNamePostfix = ".txt";
        FILE *FilePtr;
        int FileBrowser;
        int i, j, k, countNeigh;
        char *line;
        char c;

        strcpy(FileName, FileNamePrefix);
        strcat(FileName, FNum);
        strcat(FileName, FileNamePostfix);

        FilePtr = fopen(FileName, "r");

        if(!FilePtr)
                printf("Can't open file \"%s\"\n", FileName);
        else
        {
                if(!fscanf(FilePtr, "%d", &FileBrowser))
                        printf("fscanf error 1!\n");

                G->Num = FileBrowser;
                G->Nodes = malloc(G->Num * sizeof *(G->Nodes));
                if(G->Nodes == NULL)
                {
                        printf("Memory allocation error 1!\n");
                        return;
                }

                for(i = 0; i < G->Num; i++)
                {
                        G->Nodes[i] = malloc(sizeof *(G->Nodes[i]));
                        if(G->Nodes[i] == NULL)
                        {
                                printf("Memory allocation error 2!\n");
                                return;
                        }
                }

                line = malloc((2*G->Num + 1) * sizeof *line );
                if(line == NULL)
                {
                        printf("Memory allocation error 3!\n");
                        return;
                }


                i = 0;
                if(!fscanf(FilePtr, "%c", &c))
                        printf("fscanf error 2!\n");

                while(!feof(FilePtr))
                {
                       if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
                         printf("fgets error 1!\n");

                        countNeigh = 0;
                        j = 0;
                        while(line[j] != '\0')
                        {
                                if(line[j] == '1')
                                        countNeigh++;
                                j++;
                        }
                        G->Nodes[i]->Deg = countNeigh;
                        G->Nodes[i]->Val = i;
                        G->Nodes[i]->Neigh = malloc(countNeigh * sizeof *(G->Nodes[i]->Neigh));
                        if(G->Nodes[i]->Neigh == NULL)
                        {
                                printf("Memory allocation error 4!\n");
                                return;
                        }


                        j = 0;
                        k = 0;
                        while(line[j] != '\0')
                        {
                                if(line[j] == '1')
                                {
                                        G->Nodes[i]->Neigh[k] = j/2;
                                        k++;
                                }
                                j++;
                        }

                        i++;
                }

                free(line);
        }

        fclose(FilePtr);
}

void GPrint(const tGraphPtr G)
{
        int j, k;
        int i;

        printf("Graph demonstration:\n");
        for(j = 0; j < G->Num; j++)
        {
                printf("I'm Node: %d , my degree is: %d and my neighbours are:\t", G->Nodes[j]->Val, G->Nodes[j]->Deg);
                for(k = 0; k < G->Nodes[j]->Deg; k++)
                        printf("%3d", G->Nodes[j]->Neigh[k]);
                printf("\n");
        }

        for(i = 0; i < G->Num; i++)
        {
                free (G->Nodes[i]->Neigh);
                free (G->Nodes[i]);
        }

        free (G->Nodes);
}

void GDelete(tGraphPtr G)
{

}

int main(int argc, char *argv[])
{

        tGraphPtr TmpGraph;
        char *FNum;
        FNum = "1";

        TmpGraph = malloc(sizeof *TmpGraph);
        if(TmpGraph == NULL)
        {
                printf("Memory allocation error 5!\n");
                return -1;
        }

        GInit(TmpGraph, FNum);

        GPrint(TmpGraph);

        free (TmpGraph);

        return(0);
}

Valgrind报告的内存泄漏:

eva ~/Algoritmy/Euler> gcc -g Euler.c -o Euler
Euler.c:166:2: warning: no newline at end of file
eva ~/Algoritmy/Euler>  valgrind --leak-check=yes --show-reachable=yes  ./Euler
==39575== Memcheck, a memory error detector
==39575== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==39575== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==39575== Command: ./Euler
==39575==
Graph demonstration:
I'm Node: 0 , my degree is: 2 and my neighbours are:      1  3
I'm Node: 1 , my degree is: 4 and my neighbours are:      0  2  4  5
I'm Node: 2 , my degree is: 4 and my neighbours are:      1  3  4  5
I'm Node: 3 , my degree is: 2 and my neighbours are:      0  2
I'm Node: 4 , my degree is: 2 and my neighbours are:      1  2
I'm Node: 5 , my degree is: 2 and my neighbours are:      1  2
==39575==
==39575== HEAP SUMMARY:
==39575==     in use at exit: 4,096 bytes in 1 blocks
==39575==   total heap usage: 17 allocs, 16 frees, 37,101 bytes allocated
==39575==
==39575== 4,096 bytes in 1 blocks are still reachable in loss record 1 of 1
==39575==    at 0x100688B: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==39575==    by 0x130CC7A: ??? (in /lib/libc.so.7)
==39575==    by 0x130CB34: ??? (in /lib/libc.so.7)
==39575==    by 0x130C81D: ??? (in /lib/libc.so.7)
==39575==    by 0x12E1538: puts (in /lib/libc.so.7)
==39575==    by 0x400DA5: GPrint (Euler.c:122)
==39575==    by 0x400F44: main (Euler.c:161)
==39575==
==39575== LEAK SUMMARY:
==39575==    definitely lost: 0 bytes in 0 blocks
==39575==    indirectly lost: 0 bytes in 0 blocks
==39575==      possibly lost: 0 bytes in 0 blocks
==39575==    still reachable: 4,096 bytes in 1 blocks
==39575==         suppressed: 0 bytes in 0 blocks
==39575==
==39575== For counts of detected and suppressed errors, rerun with: -v
==39575== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

我正在读取的文件Graph1.txt是一个入射矩阵,开头有多个节点。最后没有换行符。

6
0 1 0 1 0 0
1 0 1 0 1 1
0 1 0 1 1 1
1 0 1 0 0 0
0 1 1 0 0 0
0 1 1 0 0 0

感谢您的建议。 约翰。

1 个答案:

答案 0 :(得分:1)

我很确定这是printf()使用的内部缓冲区,无需担心(当然也不是代码问题)。

请参阅this,了解valgrind中“仍然可达”的含义的详细说明。