2010-10-26 174 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