valgrind'尺寸的写作无效n&quot使用malloc时
我正在使用此结构创建图形
struct node
{
int id;
struct node *ad;
};
struct graph
{
int numVert;
struct node **adjList;
int *visited;
int *back;
};
,并使用它来分配内存,
static struct graph *graph_create(struct world *W, int v)
{
struct graph *G = NULL;
if ((G = graph_alloc(v)) != NULL)
{
/* some stuff */
}
return G;
}
static struct graph *graph_alloc(int v)
{
struct graph *G = NULL;
int i;
struct node **newNode = NULL;
if ((G = (struct graph *)malloc(sizeof(struct graph *))) != NULL)
{
G->numVert = v;
G->adjList = (struct node **)malloc(v * sizeof(struct node *));
}
/* other stuff */
return G;
}
但是当我使用-s-leak-check = full-show-show-show-leak-kinds = all
进行编译时,Valgrind向我展示了这一点。而且我不知道为什么
==65390== Invalid write of size 8
==65390== at 0x10985D: graph_alloc (main.c:299)
==65390== by 0x109801: graph_create (main.c:283)
==65390== by 0x10925F: main (main.c:75)
==65390== Address 0x4a429c8 is 0 bytes after a block of size 8 alloc'd
==65390== at 0x483F7B5: malloc (vg_replace_malloc.c:381)
==65390== by 0x109830: graph_alloc (main.c:296)
==65390== by 0x109801: graph_create (main.c:283)
==65390== by 0x10925F: main (main.c:75)
我认为问题是那排没有它,没有错误
G->adjList = (struct node **)malloc(v * sizeof(struct node *));
I'm creating a graph using this structures
struct node
{
int id;
struct node *ad;
};
struct graph
{
int numVert;
struct node **adjList;
int *visited;
int *back;
};
And using this to allocate the memory
static struct graph *graph_create(struct world *W, int v)
{
struct graph *G = NULL;
if ((G = graph_alloc(v)) != NULL)
{
/* some stuff */
}
return G;
}
static struct graph *graph_alloc(int v)
{
struct graph *G = NULL;
int i;
struct node **newNode = NULL;
if ((G = (struct graph *)malloc(sizeof(struct graph *))) != NULL)
{
G->numVert = v;
G->adjList = (struct node **)malloc(v * sizeof(struct node *));
}
/* other stuff */
return G;
}
But valgrind show me this when i compile using -s --leak-check=full --show-leak-kinds=all
and i don't know why
==65390== Invalid write of size 8
==65390== at 0x10985D: graph_alloc (main.c:299)
==65390== by 0x109801: graph_create (main.c:283)
==65390== by 0x10925F: main (main.c:75)
==65390== Address 0x4a429c8 is 0 bytes after a block of size 8 alloc'd
==65390== at 0x483F7B5: malloc (vg_replace_malloc.c:381)
==65390== by 0x109830: graph_alloc (main.c:296)
==65390== by 0x109801: graph_create (main.c:283)
==65390== by 0x10925F: main (main.c:75)
I think the problem is that row becouse without it there is no error
G->adjList = (struct node **)malloc(v * sizeof(struct node *));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您尝试在此处为图形结构分配内存时:
您仅为指向结构的指针分配内存,但是您需要为指针指向的内容分配内存:
您还可以指定类型的大小:
但是我喜欢成语
类型 *p = malloc(sizeof( *p))
。您从malloc
获得的指针是您分配给定尺寸的内存的处理。重要的不是指针的大小重要,而是指向指向的大小,即*p
。在您的情况下,图形结构由三个指针和一个整数组成,因此图形结构比指向图形结构的指针所需的内存更多。这就是导致无效写作的原因。
两个观察结果:
在C中,铸件对
(struct Graph *)
是不需要的,因为void *
可以转换为指针转换为其他东西。我发现在子句中同时进行分配和null检查
,从而使代码很难看到正在发生的事情。而不是
我更喜欢:
将内存分配与成功测试分开。它的括号也更少。
:)
(这也许是个人品味的问题,但我的印象是初学者非常喜欢这些复杂的结构。保持简单。)When you try to allocate memory for your graph structure here:
you allocate memory only for a pointer to the structure, but you need to allocate memory for the thing the pointer points at:
You could also specify the size of the type:
but I like the idiom
Type *p = malloc(sizeof(*p))
. The pointer you get frommalloc
is a handle to the memory of the given size you have allocated. It's not the size of the pointerp
that matters, but the size of what it points to, namely*p
.In your case the graph struct is made up of three pointers and an integers, so the graph struct requires more memory than a pointer to the graph struct. That is what causes the invalid writes.
Two observations:
In C, the cast to
(struct graph *)
is not necessary, becausevoid *
can be converted to a pointer to something else.I find doing both the assignment and the null check in the
if
clause clutters the code and makes it hard to see what's going on. Instead ofI'd prefer:
which separates the memory allocation from the test for success. It also has way fewer parentheses.
:)
(That's a matter of personal taste perhaps, but my impression is that beginners are very fond of these complicated constructions. Keep it simple.)