我一直在做一个学校项目,似乎没有正确地分配所有内存。我不知道我在哪里错过了使用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] != ' ')
{
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] != ' ')
{
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
谢谢你的建议。约翰。
我确信这是printf()
使用的内部缓冲区,无需担心(当然这对您的代码来说不是问题)。
有关valgrind中"仍然可达"的详细解释,请参阅此。