[英]Valgrind malloc invalid writes and reads in C
I have written the following program in C.我用 C 编写了以下程序。
#include<stdio.h>
#include<stdlib.h>
struct stack{
int *arr;
int top;
};
struct stack* init(int size){
struct stack *s=NULL;
s=malloc(sizeof(struct stack));
s->arr=malloc(sizeof(int) * (size));
s->top=-1;
return s;
}
void push(struct stack* t, int val){
++(t->top);
t->arr[t->top]=val;
}
void pop(struct stack* t){
if(t->top != -1)
t->top--;
}
int peek(struct stack *t){
if(t->top != -1)
return t->arr[t->top];
return -1;
}
int isEmpty(struct stack *t){
if(t->top == -1)
return 1;
return 0;
}
int adjVisited(int n, int **g, int i){
for(int j=0;j<n;j++){
if(g[i][j] == 1)
return 0;
}
return 1;
}
void Euler(int v, int n, int **g, int e){
struct stack *temp=init(e+2);
struct stack *ans=init(e+2);
push(temp, v);
while(!isEmpty(temp)){
int u=peek(temp);
if(adjVisited(n, g, u)){
push(ans, u);
pop(temp);
}
else{
for(int j=0;j<n;j++){
if(g[u][j] == 1){
push(temp, j);
g[u][j] = 0;
g[j][u] = 0;
break;
}
}
}
}
free(temp->arr);
free(temp);
while(!isEmpty(ans)){
printf("%d ", peek(ans));
pop(ans);
}
}
void addEdge(int n, int** g, int u, int v){
g[u][v]=1;
g[v][u]=1;
}
int main(){
int n, e, x, y;
printf("Enter number of nodes in the graph\n");
scanf("%d", &n);
int **graph = (int **)calloc(n, sizeof(int *));
for (int i=0; i<n; i++)
graph[i] = (int *)calloc(n, sizeof(int));
printf("Enter number of edges in the graph\n");
scanf("%d", &e);
printf("Enter end vertices of the edge to be added\n");
while(e--){
scanf("%d %d", &x,&y);
addEdge(n, graph, x, y);
}
Euler(0, n, graph, e);
for(int i=0;i<n;i++)
free(graph[i]);
free(graph);
return 0;
}
Valgrind throws me invalid write and invalid read error. Valgrind 抛出无效写入和无效读取错误。 This is the first time that I have come across this error.这是我第一次遇到这个错误。 From what I know about it, it occurs whenever I want to write data to a memory location that has not been dynamically allocated.据我所知,每当我想将数据写入尚未动态分配的内存位置时,就会发生这种情况。
==4199== Memcheck, a memory error detector
==4199== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4199== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==4199== Command: ./a.out
==4199==
Enter number of nodes in the graph
6
Enter number of edges in the graph
6
Enter end vertices of the edge to be added
0 1
1 2
2 3
3 4
4 5
5 0
==4199== Invalid write of size 4
==4199== at 0x109294: push (hier.c:31)
==4199== by 0x109477: Euler (hier.c:75)
==4199== by 0x1096D4: main (hier.c:114)
==4199== Address 0x4a52bc4 is 0 bytes after a block of size 4 alloc'd
==4199== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4199== by 0x10923E: init (hier.c:24)
==4199== by 0x1093AA: Euler (hier.c:60)
==4199== by 0x1096D4: main (hier.c:114)
==4199==
==4199== Invalid read of size 4
==4199== at 0x1092F4: peek (hier.c:41)
==4199== by 0x1093F2: Euler (hier.c:66)
==4199== by 0x1096D4: main (hier.c:114)
==4199== Address 0x4a52bc4 is 0 bytes after a block of size 4 alloc'd
==4199== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4199== by 0x10923E: init (hier.c:24)
==4199== by 0x1093AA: Euler (hier.c:60)
==4199== by 0x1096D4: main (hier.c:114)
==4199==
==4199== Invalid write of size 4
==4199== at 0x109294: push (hier.c:31)
==4199== by 0x10941E: Euler (hier.c:69)
==4199== by 0x1096D4: main (hier.c:114)
==4199== Address 0x4a52c64 is 0 bytes after a block of size 4 alloc'd
==4199== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4199== by 0x10923E: init (hier.c:24)
==4199== by 0x1093CC: Euler (hier.c:62)
==4199== by 0x1096D4: main (hier.c:114)
==4199==
==4199== Invalid read of size 4
==4199== at 0x1092F4: peek (hier.c:41)
==4199== by 0x10951A: Euler (hier.c:86)
==4199== by 0x1096D4: main (hier.c:114)
==4199== Address 0x4a52c78 is 20 bytes after a block of size 4 alloc'd
==4199== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4199== by 0x10923E: init (hier.c:24)
==4199== by 0x1093CC: Euler (hier.c:62)
==4199== by 0x1096D4: main (hier.c:114)
==4199==
EDIT: I get this error when testing for the following input编辑:测试以下输入时出现此错误
6 as number of vertices
9 as number of edges
0 1
1 2
2 3
3 4
4 5
5 0
0 2
2 4
0 4 as the edges of the graph
Can anyone help me resolve this error?谁能帮我解决这个错误?
You assign the number of edges to variable e
, in your example e == 9
.您将边数分配给变量e
,在您的示例中e == 9
。
Then you have a while loop where you decrease e
while reading in the edges:然后你有一个 while 循环,你在阅读边缘时减少e
:
while (e--)
{ ... }
After that e
will be -1
.之后e
将是-1
。
The you call Euler
with e==-1
as an argument.你用e==-1
作为参数调用Euler
。 You allocate memory in arr
for -1 + 2 == 1
elements, which is not enough for the 9 edges.您在arr
为-1 + 2 == 1
元素分配内存,这对于 9 个边来说是不够的。
Upon the second call to push
you try to write to element index 1
in arr
which is not allocated.在第二次调用push
您尝试写入未分配的arr
元素索引1
。 Thus valgrind reposts that you write of size 4 to an address which is 0 bytes after a block of size 4 .因此,valgrind 将您写入大小为 4的地址重新发布到大小为 4的块之后的 0 字节地址。
You overflow your stacks.你溢出你的堆栈。 Add some logging to push
and you will see this happen.添加一些日志来push
,你会看到这种情况发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.