gpt4 book ai didi

c - 大小 8 2 的读/写无效

转载 作者:行者123 更新时间:2023-11-30 17:42:47 26 4
gpt4 key购买 nike

在我的学校项目上工作时,在 Unix 学校服务器上编译我的项目后,我不断收到来自 Valgrind 的以下错误,并且无法运行该程序,因为我收到“段错误: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

如果您有任何关于如何修复此错误的建议,我们将不胜感激。顺便说一句,Microsoft VS2013 成功构建了此代码(当在 malloc 之前使用类型转换时)并且运行没有错误。谢谢。约翰

最佳答案

您是否尝试从“Graph.txt”的最后一行中删除换行符并运行二进制文件?

此外,您应该对 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);
}

valgrind 的操作

[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 末尾没有有换行符。

关于c - 大小 8 2 的读/写无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20420824/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com