簡體   English   中英

結構內固定大小數組的內存分配

[英]Memory allocation of fixed size array inside a struct

我有以下樹節點結構,該結構保存指向其他樹節點的指針:

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

這個想法是,我要檢查是否有node*里面children和基礎和更深入的樹。 因此,當我分配node我想讓children擁有20個NULL值。 目前我不在

  1. 我應該如何分配此數組,以免出現諸如Conditional jump or move depends on uninitialised value(s)類的錯誤,該錯誤Conditional jump or move depends on uninitialised value(s) (Valgrind)?
  2. 每次分配新節點時,使用struct node** children並分配固定大小會更好嗎?

編輯: Valgrind抱怨的一個地方的例子:

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

在分配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;
}

不能隨便n->children上使用memset() 或在 calloc() ,因為這些將給您“所有位為零”,這與“指針NULL ”不同。

您的struct定義是有效的(盡管沒有更多上下文很難確定它是否滿足您的要求)。

Valgrind不抱怨您的結構定義,它可能抱怨您如何實例化該類型的變量。 確保所有數組成員都已初始化,並且投訴很可能會消失。

問題是您在if條件中使用的是非初始化值。

當實例化一個struct node ,它的成員struct node* children[20]; 是由20個struct node *的數組,所有這些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 ,情況將不會有太大不同-您仍然需要初始化所有成員,包括數組的元素。 您可以使用calloc使其更短一些,它將所有字節初始化為0 ; 再一次,您將需要一些代碼來進行正確的重新分配(並記住要這樣做),所以我認為這種權衡是不值得的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM