我有一个看起来像这样的结构:
typedef struct{
char* name;
int count;
Node **subnodes;
}Node;
我为整个k-ary树逐一接收名称并统计网络,然后重建树。我如何malloc这个结构?
Node *n = NULL;
fun(n, buf); //call function fun
void fun(Node *n, void *buf){
//successfully extracted name and count from buf
// say count is 5, i.e. this node should have 5 subnodes and
// name is root
n = malloc(sizeof(*n)+strlen(name));
n->name = name;
n->count = count;
for(int i=0; i<n->count;i++)
fun(n->subnodes[i], buf+some_increment);
}
一旦我第二次打电话,这就崩溃了。我应该怎样malloc正确?我应该对每个子节点进行动画制作吗?
答案 0 :(得分:3)
首先,你意识到这是漏洞吗? n
只是在堆栈中 - 你没有返回它或者#34;保存&#34;你永久地给它的价值。
然后你还没有为subnodes
分配任何内存,所以通过索引你正在读取未分配的内存。
如果没有更完整的例子,很难进一步,但至少你需要为subnodes
malloc。
答案 1 :(得分:3)
是的,您必须对每个节点进行malloc操作。我在这里看到了几个问题:
您在malloc(sizeof(*n)+strlen(name))
忽略为null终止符提供空间。该声明应为malloc(sizeof(*n)+strlen(name)+1)
。你还应该在结构中将名称指针设置到结构的末尾,然后将缓冲的名称strcpy到它
n -> name = (char *)(n + 1)
strcpy(n -> name, buffered_name)
我认为缓冲版本是暂时的。
您没有为可变大小的子节点数组分配空间。这必须作为一个单独的malloc完成,或者你必须将它嵌入Node malloc(我建议将它放在Node头和名称字符串内容之间。
注意,我对代码的真实情况做了一些自由的假设,因为这显然是一个不完整的错别字。例如子节点&lt; - &gt;子节点
附录:代码段(未经测试,因此可以采用正常的警告):
typedef struct
{
char* name;
int count;
Node **subnodes;
}
Node;
Node *fun(void *buf)
{
...
//successfully extracted name and count from buf
// say count is 5, i.e. this node should have 5 subnodes and
// name is root
// Allocate space for the node and its data.
Node *node_ptr = malloc(sizeof(Node) + count * sizeof(Node *) + strlen(name) + 1);
// Set the name pointer and copy the name from the I/O buffer.
node_ptr -> name = (char *)(node_ptr + 1) + count * sizeof(Node *); // set the name pointer to the right location.
strcpy(node_ptr -> name, name); // copy the buffered value to the node value.
// Establish the count from the I/O buffer.
node_ptr -> count = count;
// Set the subnodes address.
node_ptr -> subnodes = (char *)(node_ptr + 1);
// Get the child nodes.
for(int child = 0; child < node_ptr -> count; child++)
node_ptr -> subnodes[child] = fun(buf + some_increment);
}
答案 2 :(得分:1)
我有一个看起来像这样的结构:
typdef struct{
char* name;
int count;
Node **subnodes;
}Node;
不是,因为typedef
不是typdef
。
正如John3136所指出的那样,你的函数在n
中分配内存,这是一个局部变量。另外,您指定的count
和name
似乎没有传递给fun
。
在我看来,函数fun
将无限递归。
您调用fun
(在最后一行)调用fun
,因此再次调用fun
,依此类推,直到您的用完为止。
(已编辑添加)
尝试猜测想要什么,我已经有了这个实例:
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct Node {
char* name;
int count;
Node **subnodes;
}Node;
void makeNode(Node * &n, const char * name, const int count)
{
// make the node itself
n = (Node *) malloc(sizeof(*n));
// allocate room for the name
n->name = (char *) malloc (strlen (name) + 1);
// copy in the name
strcpy (n->name, name);
// save the count of subnodes
n->count = count;
// allocate memory for subnode pointers (not the subnodes themselves)
if (count > 0)
n->subnodes = (Node **) malloc (sizeof (Node *) * count);
else
n->subnodes = NULL;
} // end of makeNode
int main ()
{
Node *node = NULL;
makeNode(node, "foo", 3);
makeNode(node->subnodes [0], "the", 0);
makeNode(node->subnodes [1], "slithy", 0);
makeNode(node->subnodes [2], "toves", 0);
for (int i = 0; i < 3; i++)
printf ("Node %i, name = %s\n", i, node->subnodes [i]->name);
printf ("Done!\n");
} // end of main
运行正常:
Node 0, name = the
Node 1, name = slithy
Node 2, name = toves
Done!
注意,我用g ++编译,而不是gcc。但是它应该给你一些想法。
(你没有C中的引用,所以你真的需要C ++才能工作)