带有双指针的malloc结构

时间:2016-02-06 03:08:52

标签: c pointers struct malloc

我有一个看起来像这样的结构:

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正确?我应该对每个子节点进行动画制作吗?

3 个答案:

答案 0 :(得分:3)

首先,你意识到这是漏洞吗? n只是在堆栈中 - 你没有返回它或者#34;保存&#34;你永久地给它的价值。

然后你还没有为subnodes分配任何内存,所以通过索引你正在读取未分配的内存。

如果没有更完整的例子,很难进一步,但至少你需要为subnodes malloc。

答案 1 :(得分:3)

是的,您必须对每个节点进行malloc操作。我在这里看到了几个问题:

  1. 您在malloc(sizeof(*n)+strlen(name))忽略为null终止符提供空间。该声明应为malloc(sizeof(*n)+strlen(name)+1)。你还应该在结构中将名称指针设置到结构的末尾,然后将缓冲的名称strcpy到它

    n -> name = (char *)(n + 1) strcpy(n -> name, buffered_name)

    我认为缓冲版本是暂时的。

  2. 您没有为可变大小的子节点数组分配空间。这必须作为一个单独的malloc完成,或者你必须将它嵌入Node malloc(我建议将它放在Node头和名称字符串内容之间。

  3. 注意,我对代码的真实情况做了一些自由的假设,因为这显然是一个不完整的错别字。例如子节点&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中分配内存,这是一个局部变量。另外,您指定的countname似乎没有传递给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 ++才能工作)