[英]Memory allocation of fixed size array inside a struct
我有以下樹節點結構,該結構保存指向其他樹節點的指針:
struct node {
// ...
struct node* children[20];
}
這個想法是,我要檢查是否有node*
里面children
和基礎和更深入的樹。 因此,當我分配node
我想讓children
擁有20個NULL
值。 目前我不在
Conditional jump or move depends on uninitialised value(s)
類的錯誤,該錯誤Conditional jump or move depends on uninitialised value(s)
(Valgrind)? 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.