结构内部固定大小数组的内存分配

时间:2015-04-23 06:44:48

标签: c arrays struct

我有以下树节点结构,它包含指向其他树节点的指针:

struct node {
    // ...
    struct node* children[20];
}

我的想法是,我想检查node*内部是否有children并且更深入到树中。因此,当我分配node时,我希望children包含20 NULL个值。 目前我不是在做什么

  1. 我应该如何分配此数组以避免出现Conditional jump or move depends on uninitialised value(s)(Valgrind)等错误?
  2. 每次分配新节点时,使用struct node** children并分配固定大小会更好吗?
  3. 编辑: Valgrind抱怨的一个地方的例子:

    for(int i=0;i<20;i++)
      if(node->children[i] != NULL)
        do_something_with_the_node(node->children[i]);
    

3 个答案:

答案 0 :(得分:1)

当您分配struct node的新实例时,必须将包含的指针设置为NULL,以将其标记为“不指向任何位置”。这将使Valgrind警告消失,因为指针将不再是未初始化的。

这样的事情:

struct node * node_new(void)
{
  struct node *n = malloc(sizeof *n);
  if(n != NULL)
  {
    for(size_t i = 0; i < sizeof n->children / sizeof *n->children; ++i)
      n->children[i] = NULL;
  }
  return n;
}

无法memset() n->children上轻松使用calloc(),因为这些将为您提供“所有位为零”这与“指针NULL”不同。

答案 1 :(得分:0)

你的结构定义是有效的(尽管如果符合你的要求,没有更多的上下文很难说明。)

Valgrind并没有抱怨你的结构定义,它可能会抱怨你如何实例化那种类型的变量。确保所有阵列成员都已初始化,投诉很可能会消失。

答案 2 :(得分:0)

问题是您在if条件下使用未初始化的值。

当您实例化struct node时,其成员struct node* children[20];是一个20 struct node *的数组,所有这些都未初始化。

与此无异:

char *x;

if (x == NULL) {
    /* Stuff */
}

此时,x可能确实具有任何价值。在您的示例中,数组的任何元素都可以具有任何值。

要解决此问题,您需要在使用它们之前初始化数组元素,例如:

for (int i = 0; i < 20; ++i) {
    node->children[i] = NULL;
}

或更短:

memset(node->children, 0, 20);

如果您将会员更改为node **children,那么情况可能会有所不同 - 您仍然需要初始化所有成员,包括数组& #39; s元素。你可以使用calloc缩短它,这会将所有字节初始化为0;再说一遍,你需要一些代码才能正确释放(并且记得这样做),所以我认为权衡不值得。