在我的学校项目工作期间,在Unix学校服务器上编译项目后,我一直收到Valgrind的错误信息。
==2951== Memcheck, a memory error detector
==2951== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==2951== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==2951== Command: ./Euler
==2951==
==2951== Invalid read of size 8
==2951== at 0x400B65: GInit (Euler.c:64)
==2951== by 0x400DD1: main (Euler.c:118)
==2951== Address 0x1786100 is 0 bytes after a block of size 48 alloc'd
==2951== at 0x100688B: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==2951== by 0x400A80: GInit (Euler.c:43)
==2951== by 0x400DD1: main (Euler.c:118)
==2951==
==2951== Invalid write of size 4
==2951== at 0x400B6B: GInit (Euler.c:64)
==2951== by 0x400DD1: main (Euler.c:118)
==2951== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2951==
==2951==
==2951== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==2951== Access not within mapped region at address 0x0
==2951== at 0x400B6B: GInit (Euler.c:64)
==2951== by 0x400DD1: main (Euler.c:118)
==2951== If you believe this happened as a result of a stack
==2951== overflow in your program's main thread (unlikely but
==2951== possible), you can try to increase the size of the
==2951== main thread stack using the --main-stacksize= flag.
==2951== The main thread stack size used in this run was 16777216.
==2951==
==2951== HEAP SUMMARY:
==2951== in use at exit: 32,981 bytes in 16 blocks
==2951== total heap usage: 16 allocs, 0 frees, 32,981 bytes allocated
==2951==
==2951== LEAK SUMMARY:
==2951== definitely lost: 0 bytes in 0 blocks
==2951== indirectly lost: 0 bytes in 0 blocks
==2951== possibly lost: 0 bytes in 0 blocks
==2951== still reachable: 32,981 bytes in 16 blocks
==2951== suppressed: 0 bytes in 0 blocks
==2951== Reachable blocks (those to which a pointer was found) are not shown.
==2951== To see them, rerun with: --leak-check=full --show-reachable=yes
==2951==
==2951== For counts of detected and suppressed errors, rerun with: -v
==2951== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault: 11
使用malloc时,我似乎错误地分配了内存。我知道没有释放内存,因为我还没有实现删除功能。
函数GInit
应从文件Graph1.txt
读取格式化数据,并创建由节点组成的图形。文件包含节点数和关联矩阵。
这是我的代码:
#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
{
fscanf(FilePtr, "%d", &FileBrowser);
G->Num = FileBrowser;
G->Nodes = (tNodePtr*) malloc(sizeof(tNodePtr) * G->Num);
for(i = 0; i < G->Num; i++)
G->Nodes[i] = (tNodePtr) malloc(sizeof(struct tNode));
line = (char*) malloc(sizeof(char) * (2*G->Num + 1));
i = 0;
fscanf(FilePtr, "%c", &c);
fgets(line, 2*G->Num + 1, FilePtr);
while(!feof(FilePtr))
{
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 = (int*) malloc(sizeof(int) * countNeigh);
j = 0;
k = 0;
while(line[j] != '\0')
{
if(line[j] == '1')
{
G->Nodes[i]->Neigh[k] = j/2;
k++;
}
j++;
}
i++;
fgets(line, 2*G->Num + 1, FilePtr);
}
free(line);
}
fclose(FilePtr);
}
void GPrint(const tGraphPtr G)
{
int j, k;
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");
}
}
void GDelete(tGraphPtr G)
{
}
int main(int argc, char *argv[])
{
tGraphPtr TmpGraph;
char *FNum;
FNum = "1";
TmpGraph = (tGraphPtr) malloc(sizeof(struct tGraph));
GInit(TmpGraph, FNum);
GPrint(TmpGraph);
return(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
如何解决此错误的任何建议表示赞赏。 BTW Microsoft VS2013成功构建此代码并运行,没有错误。 谢谢。 约翰
答案 0 :(得分:2)
您应该进行更多错误检查。以下是一些地方:
fscanf(FilePtr, "%d", &FileBrowser)
您假设fscanf
已成功从文件中检索int
。您应该通过验证从fscanf
返回的值是1来检查这一点。如果它为0,则您在FileBrowser
中有一个垃圾值。
这是另一个问题:
G->Nodes = (tNodePtr*) malloc(sizeof(tNodePtr) * G->Num);
首先,没有必要对malloc
的返回进行类型转换,因此请删除(tNodePtr*)
。其次,你再次假设malloc
成功了。您应该通过比较G->Nodes
到NULL
的地址来确保确实这样做。 NULL
表示失败。
答案 1 :(得分:0)
只是为了扩展Bit Fiddling Code Monkey的响应,Valgrind抱怨读取错误和第64行写错,这是:
G->Nodes[i]->Deg = countNeigh;
意味着您要超越节点的大小(错误读取Nodes[i]
)并写入未分配的内存地址(Deg
中的错误写入)。
这可能是因为fscanf失败或因为该文件包含最初在FileBrowser
中声明的更多行。例如,文件末尾的额外空行会导致无效的读/写。