2010-10-26 172 views
2

我有一个结构是一个节点,另一个是这些节点的列表。在列表结构,其节点的数组,而是数组,这是一个指针的大小整数指针:如何初始化指针指向C中的指针结构?

typedef struct node { 
    struct node *next; 
    MyDef *entry; 
} Node; 


typedef struct list { 
    Node **table; 
    int size; 
} List; 

List *initialize(void) 
{ 
    List *l; 
    Node **n; 

    if ((l = (List *)malloc(sizeof(List))) == NULL) 
     return NULL; 
    l->size = 11; 

    /* I think this is correctly allocating the memory for this 'array' of nodes */ 
    if ((n = (Node **)malloc(l->size * sizeof(Node))) == NULL) 
     return NULL; 

    /* Now, how do I set MyDef *entry and Node *next to NULL for each of the 'array'? */ 

    l->table = n; 

    return l; 
} 

如何设置MyDef *入境和节点*旁边NULL为每'数组'?

+0

太多星星...你使用'**'作为“2D数组”,而不是用于“简单”元素列表 – pmg 2010-10-26 09:56:43

+0

取自:http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_hashtable.aspx – 2010-10-26 10:01:23

回答

1

(Node **)是指向[指向数组]的指针的指针,因此您分配的数组不会有任何结构成员。

您应该使用(Node *),然后您将指向节点结构数组,或分别分配每个节点,然后将指针指向它们到您的数组中。在你的情况下存在标准C库中的函数calloc():它以0(对应于(char/short/int/long)0,0.0和NULL)分配区域。

还有内存泄漏。

/* I think this is correctly allocating the memory for this 'array' of nodes */ 
if (... == NULL) 
    return NULL; 

当数组分配失败时,您不会空闲列表,但会丢失指向它的指针。重写为:

/* I think this is correctly allocating the memory for this 'array' of nodes */ 
if ((n = (Node **)malloc(l->size * sizeof(Node))) == NULL) { 
    free(l); 
    return NULL; 
} 
从我wiev点

所以正确的代码是:

typedef struct node { 
    struct node *next; 
    MyDef *entry; 
} Node; 


typedef struct list { 
    Node *table; /* (!) single asterisk */ 
    int size; 
} List; 

List *initialize(void) 
{ 
    List *l; 
    Node **n; 

    if ((l = (MList *)malloc(sizeof(List))) == NULL) 
     return NULL; 
    l->size = 11; 

    /* I think this is correctly allocating the memory for this 'array' of nodes */ 
    if ((n = (Node *)calloc(l->size, sizeof(Node))) == NULL) 
    { 
     free(l); 
     return NULL; 
    } 

    /* Now, how do I set MyDef *entry and Node *next to NULL for each of the 'array'? */ 

    l->table = n; 

    return l; 
} 

Futhermore C99使您可以可变大小的结构,所以你可以初始化结构像

typedef struct list { 
    int size; 
    Node table[0] 
} List; 

并根据需要使用 malloc(sizeof(List)+ sizeof(Node)* n)分配尽可能多的节点。

+0

非常感谢您花时间做到这一点。我正在尝试这个,因为我输入这个。 – 2010-10-26 16:21:30

+0

刚试过这个,虽然这个位工作得很好,但我确实认为我需要Node **。原因是,在程序的另一个位置,我执行“n> next =(* l) - > table [int val];”,其中int val的大小为< l->。这不工作没有**,因为它不是一个数组? – 2010-10-26 16:37:06

+0

n-> next是一个指向Node的指针,(l) - > table [val]是一个Node,所以你必须得到它的指针。写&((l) - > table [val])或更短(l) - > table + val(table + val指向表的第val个元素)。 Node **实际上会指向Node的指针数组,所以在这种情况下,您还应该为每个节点分配空间并将指针存储在数组元素中。 – Vovanium 2010-10-26 19:04:38

0

首先,在我看来,你在分配数组的代码中有一个错误:它应该说是sizeof(Node*)而不是sizeof(Node),因为你想分配一个指向Node的指针数组而不是一个Node对象数组。

然后你就可以通过数组列表迭代:

for (unsigned i = 0; i < l->size; ++i) 
{ 
    Node* node = l->table[ i ]; 
    node->entry = NULL; 
    node->next = NULL; 
} 

另一个提示:你真的应该检查你的初始化函数对内存泄漏的可能性。

+0

谢谢,试过这个,并得到一个错误:l->表\t \t \t CXX0030:错误:无法评估表达式 – 2010-10-26 10:01:56

+0

任何想法,为什么这是行不通的? VS 2010调试器在Node * node = l-> table [i]上断开; – 2010-10-26 10:58:59

+0

我忘了:还必须创建单个对象。但是,你的情况似乎不是问题,因为在访问表的行中已经发生了错误。但是,为了让它正确,需要像'l-> table [i] = malloc(sizeof(Node))''。 – Flinsch 2010-10-26 11:25:12