在我的学校项目工作期间,在Unix学校服务器上编译我的项目并且无法运行程序后,我一直收到Valgrind的以下错误,因为我收到“Segmentation fault:11”。
==95183== Memcheck, a memory error detector
==95183== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==95183== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==95183== Command: ./Euler
==95183==
==95183== Invalid read of size 8
==95183== at 0x400B65: GInit (Euler.c:64)
==95183== by 0x400DD1: main (Euler.c:118)
==95183== Address 0x1786100 is 0 bytes after a block of size 48 alloc'd
==95183== at 0x100688B: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==95183== by 0x400A80: GInit (Euler.c:43)
==95183== by 0x400DD1: main (Euler.c:118)
==95183==
==95183== Invalid write of size 4
==95183== at 0x400B6B: GInit (Euler.c:64)
==95183== by 0x400DD1: main (Euler.c:118)
==95183== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==95183==
==95183==
==95183== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==95183== Access not within mapped region at address 0x0
==95183== at 0x400B6B: GInit (Euler.c:64)
==95183== by 0x400DD1: main (Euler.c:118)
==95183== If you believe this happened as a result of a stack
==95183== overflow in your program's main thread (unlikely but
==95183== possible), you can try to increase the size of the
==95183== main thread stack using the --main-stacksize= flag.
==95183== The main thread stack size used in this run was 16777216.
==95183==
==95183== HEAP SUMMARY:
==95183== in use at exit: 32,981 bytes in 16 blocks
==95183== total heap usage: 16 allocs, 0 frees, 32,981 bytes allocated
==95183==
==95183== LEAK SUMMARY:
==95183== definitely lost: 0 bytes in 0 blocks
==95183== indirectly lost: 0 bytes in 0 blocks
==95183== possibly lost: 0 bytes in 0 blocks
==95183== still reachable: 32,981 bytes in 16 blocks
==95183== suppressed: 0 bytes in 0 blocks
==95183== Reachable blocks (those to which a pointer was found) are not shown.
==95183== To see them, rerun with: --leak-check=full --show-reachable=yes
==95183==
==95183== For counts of detected and suppressed errors, rerun with: -v
==95183== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault: 11
eva ~/Algoritmy/Euler> make
gcc -Wall -std=c99 -pedantic -lm -g -o Euler Euler.c
eva ~/Algoritmy/Euler> ./Euler
Segmentation fault: 11 (core dumped [obraz paměti uložen])
eva ~/Algoritmy/Euler> valgrind --leak-check=yes ./Euler
==96649== Memcheck, a memory error detector
==96649== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==96649== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==96649== Command: ./Euler
==96649==
==96649== Invalid read of size 8
==96649== at 0x400BF2: GInit (Euler.c:85)
==96649== by 0x400ECB: main (Euler.c:152)
==96649== Address 0x1786100 is 0 bytes after a block of size 48 alloc'd
==96649== at 0x100688B: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==96649== by 0x400A8E: GInit (Euler.c:44)
==96649== by 0x400ECB: main (Euler.c:152)
==96649==
==96649== Invalid write of size 4
==96649== at 0x400BF8: GInit (Euler.c:85)
==96649== by 0x400ECB: main (Euler.c:152)
==96649== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==96649==
==96649==
==96649== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==96649== Access not within mapped region at address 0x0
==96649== at 0x400BF8: GInit (Euler.c:85)
==96649== by 0x400ECB: main (Euler.c:152)
==96649== If you believe this happened as a result of a stack
==96649== overflow in your program's main thread (unlikely but
==96649== possible), you can try to increase the size of the
==96649== main thread stack using the --main-stacksize= flag.
==96649== The main thread stack size used in this run was 16777216.
==96649==
==96649== HEAP SUMMARY:
==96649== in use at exit: 32,981 bytes in 16 blocks
==96649== total heap usage: 16 allocs, 0 frees, 32,981 bytes allocated
==96649==
==96649== LEAK SUMMARY:
==96649== definitely lost: 0 bytes in 0 blocks
==96649== indirectly lost: 0 bytes in 0 blocks
==96649== possibly lost: 0 bytes in 0 blocks
==96649== still reachable: 32,981 bytes in 16 blocks
==96649== suppressed: 0 bytes in 0 blocks
==96649== Reachable blocks (those to which a pointer was found) are not shown.
==96649== To see them, rerun with: --leak-check=full --show-reachable=yes
==96649==
==96649== For counts of detected and suppressed errors, rerun with: -v
==96649== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault: 11
使用malloc时,我似乎错误地分配了内存。我知道没有释放内存,因为我还没有实现删除功能。
我为malloc,fgets和fscanf添加了一些额外的测试,以消除可能的错误。
函数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
{
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");
if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
printf("fgets error 1!\n");
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 = 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++;
if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
if(i < G->Num)
printf("fgets error 2!\n");
}
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 = malloc(sizeof *TmpGraph);
if(TmpGraph == NULL)
{
printf("Memory allocation error 5!\n");
return -1;
}
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成功构建了此代码(在malloc之前使用类型转换)并且运行时没有错误。 谢谢。 约翰
答案 0 :(得分:0)
您是否尝试从&#39; Graph.txt&#39;的最后一行删除换行符?并运行二进制文件?
此外,您应该对valgrind报告的泄漏做一些事情。检查此修改后的代码
#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 = calloc(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");
if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
printf("fgets error 1!\n");
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 = 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++;
if(fgets(line, 2*G->Num + 1, FilePtr) == NULL)
if(i < G->Num)
printf("fgets error 2!\n");
}
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);
}
[sourav@localhost ~]$ gcc -g so_test1.c -o test
[sourav@localhost ~]$ valgrind --leak-check=full ./test
==23941== Memcheck, a memory error detector
==23941== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==23941== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==23941== Command: ./test
==23941==
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
==23941==
==23941== HEAP SUMMARY:
==23941== in use at exit: 0 bytes in 0 blocks
==23941== total heap usage: 16 allocs, 16 frees, 533 bytes allocated
==23941==
==23941== All heap blocks were freed -- no leaks are possible
==23941==
==23941== For counts of detected and suppressed errors, rerun with: -v
==23941== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 8)
[sourav@localhost ~]$
好吧,我的Graph.txt 不会最后有换行符。