2010-01-26 99 views
0

我想'構造'(閱讀:malloc和memset)我的散列表c。要做到這一點,我創建了一個功能如下:我可以在c中指定一個類似Java的「構造函數」嗎?

int maketable(struct hash_entry **table, int size){ 

    table = (struct hash_entry **)malloc(size*sizeof(struct hash_entry *)); 
    int i = 0; 
    for (; i<size; i++) { 
     memset(table[i], '\0', sizeof(struct hash_entry *)); 
    } 
    return 0; 

} 

鑑於該表將被宣佈爲

struct hash_entry **table[size] 

輸入此代碼之前,當我從maketable回到我不會失去任何東西,對?

編輯: 是否合格tablemaketable()保證,只要我改變數據,要,這些變化將被保存table點?

編輯II: 我試圖指針數組分配給指針hash_entries

+1

我不明白。你在堆棧中爲變量分配內存,然後在函數中重新分配一些內容? - 此外,'table'是一個局部變量。你正在分配一些東西,並將它分配給'table',當函數返回時它將消失,導致內存泄漏。 – 2010-01-26 23:01:47

+0

問題是我也不太明白。我的struct hash_entry ** table [size]聲明是否爲我隱式分配內存?在這種情況下,當我聲明它們時,我仍然需要爲自己的hash_entrys提供malloc,對吧? – 2010-01-26 23:03:32

+1

該聲明爲指向堆棧上類型爲「hash_entry」的指針的大小爲「size」的數組分配內存。它不會爲陣列元素要指向的位置分配內存。 – 2010-01-26 23:05:01

回答

4

您的代碼正在分配給本地table變量,調用者不受影響。這導致內存泄漏。

在函數之外,你已經聲明table爲指向struct hash_entry指針的指針數組 - 我猜你只是想要一個指向數組的結構散列條目。

如果您實際上將table聲明爲數組,則不需要malloc。您只需要一個循環來將其中的每個元素設置爲NULL(不要將每個元素的memset設置爲零)。

如果目標是分配整個表,這是perhps你在找什麼:

struct hash_entry **table; 
... 
int maketable(struct hash_entry ***table, int size){ 

    *table = malloc(size* sizeof **table); 
    int i = 0; 
    for (; i<size; i++) { 
     (*table)[i] = NULL; 
    } 
    return 0; 
} 

這樣稱呼它

maketable(&table,100); 

我寧願做返回的表像這樣:

struct hash_entry ** maketable(int size){ 
    return calloc(size, sizeof(struct hash_entry *)); 
} 

如果聲明struct hash_entry **table[size]真的是你想要的,你需要告訴我們你的maketable()函數實際上應該做什麼(例如,你想要一個動態分配的'數組'作爲該表中的元素之一嗎?

2

您需要分配的malloc* table結果 - 否則它不會在函數外可見。

此外,使用這種方法的典型方法是聲明一個指向散列表的指針,並將該指針的地址傳遞給該函數。

+0

我該怎麼做? – 2010-01-26 23:06:38

+1

'* table =(struct hash_entry *)malloc ...' – 2010-01-26 23:07:38

1

不可以。您的類型不匹配。

你試圖分配散列項(即的table[i]類型是struct hash_entry)的表中,指針到hash_entries(即的table[i]類型是struct hash_entry *),或別的東西的桌子嗎?根據你的代碼的讀法,我假設第一個案例,但讓我知道如果這是錯誤的。

假設你動態分配的struct hash_entry一個表,你在來電錶的聲明應該是

struct hash_entry *table; // 1 *, no array dimension 

的功能應該是稱爲作爲

int result = maketable(&table, number_of_elements); 

定義 as

int maketable (struct hash_entry **table, size_t size) 
{ 
    int r = 0; 

    // sizeof **table == sizeof (struct hash_entry) 
    *table = malloc(sizeof **table * size); 
    // *ALWAYS* check the result of malloc() 
    if (*table) 
    { 
    size_t i; 
    for (i = 0; i < size; i++) 
     memset(&(*table)[i], 0, sizeof (*table)[i]); 
    r = 1; 
    } 
    return r; 
} 

有幾點需要指出。首先,不要投下malloc()的結果。從C89開始,您不需要,如果忘記包含stdlib.h或者沒有原型malloc()的範圍,則演員會壓縮診斷。其次,您可以在對象上使用sizeof運算符而不是類型。這可以幫助減少一些維護令人頭痛的問題(例如,如果在參數列表中更改了table的類型,則不必隨其更改sizeof呼叫)。

最後,請注意表的地址正在傳遞給函數;由於我們試圖寫入指針值,我們必須將指針傳遞給該指針。

如果你試圖創建指針表來struct hash_entry,代碼大多是相同的,間接的只是一個額外的級別:

您的來電錶的聲明應該是

struct hash_entry **table; // 2 *, no array dimension 

的功能應該是稱爲作爲

int result = maketable(&table, number_of_elements); 

定義作爲

int maketable (struct hash_entry ***table, size_t size) 
{ 
    int r = 0; 

    // sizeof **table == sizeof (struct hash_entry *) 
    *table = malloc(sizeof **table * size); 
    // *ALWAYS* check the result of malloc() 
    if (*table) 
    { 
    size_t i; 
    for (i = 0; i < size; i++) 
     (*table)[i] = NULL; 
    r = 1; 
    } 
    return r; 
} 

EDIT有一個在maketable實例中的錯誤;需要在應用下標之前取消table,即(*table)[i]。我們正在將下標應用到table指向,而不是表指針本身。

對不起,有任何混淆。

+0

我想分配一個指向hash_entries指針的表的表。 – 2010-01-27 00:51:48

+0

然後,您需要將該表聲明爲'struct hash_entry *** table;'。函數中參數的類型需要是'struct hash_entry **** table'。其他一切應該與第二個例子相同。 – 2010-01-27 04:45:38

相關問題