简体   繁体   English

具有双指针的Malloc结构

[英]Malloc struct with double pointer

I have a structure that looks like this: 我有一个看起来像这样的结构:

typedef struct{
    char* name;
    int count;
    Node **subnodes;
}Node;

I receive name and count over network one by one for the whole k-ary tree and then I reconstruct the tree. 我收到名称并通过网络对整个kary树进行逐一计数,然后重构该树。 How do I malloc this struct? 我如何分配此结构?

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);
}

This crashes as soon as I call fun for the second time. 当我第二次打电话给Fun时,它就会崩溃。 How should I malloc properly? 我应该如何正确分配? Should I be malloc-ing each subnode? 我应该分配每个子节点吗?

First off, you realise this is leaky? 首先,您意识到这是泄漏吗? n is just on the stack - you aren't returning it or "saving" the value you give it anywhere permanently. n只是在堆栈上-您不会返回它,也不会“保存”您在任何地方永久提供的值。

Then you haven't actually allocated any memory for subnodes , so by indexing into it you are reading unallocated memory. 然后,您实际上没有为subnodes分配任何内存,因此通过索引它可以读取未分配的内存。

Without a more complete example it is hard to further, but at a minimum you need to malloc something for subnodes . 没有更完整的示例,很难进行进一步的介绍,但是至少需要为subnodes分配一些内容。

Yes, you will have to malloc each node. 是的,您将必须分配每个节点。 I see a couple of issues here: 我在这里看到几个问题:

  1. You are neglecting in malloc(sizeof(*n)+strlen(name)) to provide space for the null terminator. 您忽略了malloc(sizeof(*n)+strlen(name))为空终止符提供空间。 This statement should read malloc(sizeof(*n)+strlen(name)+1) . 该语句应读取malloc(sizeof(*n)+strlen(name)+1) Also you should set the name pointer in the struct to the end of the struct and then strcpy the buffered name to it 另外,您应该将结构体中的名称指针设置为结构体的末尾,然后将缓冲的名称strcpy

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

    I presume the buffered version is transient. 我认为缓冲版本是暂时的。

  2. You are allocating no space for the variable sized array of child nodes. 您没有为子节点的可变大小数组分配空间。 This has to be done as a separate malloc or you have to embed it in the Node malloc (I'd recommend placing it between the Node header and the name string content. 这必须作为单独的malloc完成,或者您必须将其嵌入到Node malloc中(我建议将其放置在Node标头和名称字符串内容之间。

Note, I am making a few liberal assumptions about what the code really looks like since this is clearly an incomplete snippit with typos. 请注意,我对代码的实际外观做出了一些宽松的假设,因为这显然是错别字的摘录。 eg subnodes <-> subnode 例如,子节点<->子节点

Addendum: Code snippet (untested so normal caveats apply): 附录:代码段(未经测试,请注意常规说明):

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);
}

I have a structure that looks like this: 我有一个看起来像这样的结构:

  typdef struct{
        char* name;
        int count;
        Node **subnodes;
    }Node;

Not really, because it is typedef not typdef . 不是真的,因为它是typedef而不是typdef

As John3136 pointed out, your function allocates memory in n which is a local variable. 正如John3136所指出的那样,您的函数在n中分配内存, n是局部变量。 Plus you are assigning count and name which do not appear to be passed to fun . 另外,您还要分配似乎没有传递给fun countname

It also looks to me like the function fun will recurse indefinitely. 在我看来, fun函数将无限期递归。

You call fun which (in the last line) calls fun which therefore calls fun again, and so on until you run out of stack. 您调用fun (在最后一行)调用fun ,因此又调用fun ,依此类推,直到耗尽堆栈。


(Edited to add) (编辑添加)

Trying to guess what is wanted, I have got this working example going: 尝试猜测需要什么,我得到了这个工作示例:

#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

This runs OK: 运行正常:

Node 0, name = the
Node 1, name = slithy
Node 2, name = toves
Done!

Note, I compiled with g++, not gcc. 注意,我使用g ++而不是gcc进行编译。 However it should give you some ideas to go on with. 但是,它应该给您一些思路。

(You don't have references in C, so you really need C++ for this to work) (您在C中没有引用,因此您确实需要C ++才能正常工作)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM