2014-12-07 148 views
0

我使用的函數malloc和初始化一些存儲器的哈希函數,如下所示:返回一個指針,指向在一個函數malloc分配的結構

int main (int argc, char * argv []) 
{ 
    Bucket * hashTable; 
    hashTable = createHashTable(); 
    ... 
在「main.c中」

稱爲在另一個文件中的函數是這樣的:

Bucket * createHashTable() 
{ 
    Bucket * hashTable = malloc (sizeof(Bucket) * HASHSIZE); 
    int c=0; 
    for (c=0;c<HASHSIZE;c++) 
    { 
    hashTable[c].key=NULL; 
    hashTable[c].text=NULL; 
    hashTable[c].next=NULL; 
    } 
    return hashTable; 
} 

我的程序與「-pedantic -Wall」,但段錯誤完全編譯。用gdb,我得到這個:

Reading symbols from hash...done. 
(gdb) break 11 
Breakpoint 1 at 0x400990: file main.c, line 11. 
(gdb) run 
Starting program: /home/user/Projects/random/hash 

Breakpoint 1, main (argc=1, argv=0x7fffffffdf78) at main.c:11 
11 hashTable = createHashTable(); 
(gdb) print hashTable 
$1 = (Bucket *) 0x400520 <_start> 
(gdb) print * hashTable 
$2 = { 
key = 0x89485ed18949ed31 <error: Cannot access memory at address 0x89485ed18949ed31>, 
text = 0x495450f0e48348e2 <error: Cannot access memory at address 
0x495450f0e48348e2>, next = 0xc74800400a90c0c7} 
(gdb) 

與結構「鬥」的定義標題的部分:

typedef struct bucket{ 
    char * key; 
    char * text; 
    struct bucket * next; 
} Bucket; 

這是一個範圍的問題嗎?當功能完成後,它是否會損壞我的malloc'ed內存或什麼?

平臺是64位Linux,而這次從malloc()返回的地址是0x1665010--我想如果它失敗了,它將是NULL。

編輯:在這之後的下一個功能,在main.c中,嘗試添加到表中的條目:

printf("Adding banana...\n"); 
addItem("Banana", "Bananas are yellow", &hashTable); 

(是啊,是啊 - 香蕉,我知道)的功能是:

void addItem(char * key, char * data, Bucket ** table) 
{ 
    unsigned int hashkey; 
    hashkey=hash(key); 
    printf("%lu\n",strlen(key)); 
if (!table[hashkey]->text) /* SEGFAULTS HERE */ 
{ 
    table[hashkey]->key=key; 
    table[hashkey]->text=data; 
} 
else 
{ 
    Bucket * newListElement = malloc(sizeof(Bucket)); 
    newListElement->key=key; 
    newListElement->text=data; 
    newListElement->next = NULL; 
    table[hashkey]->next = newListElement; 
} 

}

+0

這似乎有效。你在哪個平臺上? 'malloc'返回一個有效的地址還是失敗(返回NULL)? – slugonamission 2014-12-07 21:04:20

+0

爲了幫助您驗證這一點,您應該提供一個完整的最簡單示例。例如,你包含哪些頭文件? 「Bucket」的定義是什麼?等等... – glglgl 2014-12-07 21:05:21

+0

等等,你確定它在這條線上崩潰了嗎?執行該行之前,您對GCC的'break 11'命令將會中斷*。 – slugonamission 2014-12-07 21:06:37

回答

1

這條線:

if (!table[hashkey]->text) 

應該是:

if (!(*table)[hashkey]->text) 

並且類似地對以下行。在這個函數中,table實際上是一個指向main中名爲hashTable的變量的指針。

解決此錯誤的另一種方法是使該函數爲Bucket *,而不傳遞hashTable的地址。似乎沒有任何功能需要知道hashTable的地址,因爲它只是把東西放在表格中。

+0

這工作,這很好,謝謝!這是否意味着它是按值傳遞的,因此對錶的更新不會超出函數範圍? – Andomonir 2014-12-07 21:51:27

+1

你不會更新函數中任何地方的'table'(除非你有更多的代碼沒有發佈)。不要將'table'與'table'指向的東西混淆。 – 2014-12-07 23:29:57

0

我試圖重現此問題,但無法成功。

所以我唯一的猜測是你可能已經省略了向主模塊提供正確的功能簽名,並且在那裏它被稱爲int createHashTable()。這應該導致一個警告,並且會讓你失去你的結果指針IFF的高32位,你有64位指針和一個32位的int

相關問題