2015-07-21 277 views
3

fid_table是指向數組指針fid_list的指針。將值指針傳遞給c函數中的指針值

我想在一個單獨的函數中初始化fid_tableNULL。我的理解是,fid_table是通過值複製的,但它是一個指針,所以不應該成爲問題。

fid_list **fid_table; 
fid_table_init(fid_table); 
assert(fid_table[0] == NULL); 

功能fid_table_init定義如下:

void fid_table_init(fid_list **fid_table){ 
    fid_table = (fid_list **) malloc(HTABLE_SIZE * sizeof(fid_list *)); 
    for(int i = 0; i < HTABLE_SIZE; i++){ 
     fid_table[i] = NULL; 
    } 
} 

能有人爲什麼這個斷言失敗詳細點嗎?

+0

是,C或C++?在C中,你不應該使用C++來投射'voiud *'。請選擇一種語言。 – Olaf

+0

@Olaf:這是C – Keeto

+0

好的,我不會問爲什麼你添加了C++標籤。所以:標準警告:不要施放'void *'。 – Olaf

回答

5

定義功能通過以下方式

void fid_table_init(fid_list ***fid_table){ 
    *fid_table = (fid_list **) malloc(HTABLE_SIZE * sizeof(fid_list *)); 
    for(int i = 0; i < HTABLE_SIZE; i++){ 
     (*fid_table)[i] = NULL; 
    } 
} 

,並調用它像

fid_table_init(&fid_table); 

在指針由值,函數涉及指針的副本通過了原有的功能。因此,副本的任何更改都不會影響原始指針。

考慮到函數的參數是它的局部變量。因此,在函數內部分配了一個內存並將其地址分配給該函數的局部變量。它是被分配的不是原始指針的局部變量。退出該函數後,其局部變量將被銷燬。原始指針什麼都不知道它的副本做了什麼

+0

這看起來有點可怕(並不意味着它是錯的!)。 Tri星功能。 – Olaf

+0

@Olaf設想它就像一顆三星級的干邑。:) –

+1

恭喜:您已解鎖[thee star programmer](http://c2.com/cgi/wiki?ThreeStarProgrammer)徽章! – bolov

5

fid_table_init函數中,fid_table是一個局部變量,它使用調用者傳遞的值進行初始化。 malloc行更改本地變量的值,它不會更改調用方中的值fid_table,因此調用代碼將永遠不會看到從malloc返回的指針。

修復代碼的最簡單方法是從fid_table_init函數返回指針的新值,並將其分配給調用者中的fid_table

fid_list **fid_table = fid_table_init(); 
assert(fid_table[0] == NULL); 

fid_list **fid_table_init(void) 
{ 
    fid_list **temp = malloc(HTABLE_SIZE * sizeof(fid_list *)); 
    for(int i = 0; i < HTABLE_SIZE; i++){ 
     temp[i] = NULL; 
    } 
    return temp; 
} 
+0

感謝您的解釋! – Keeto

+0

很高興幫助,快樂的編碼! – user3386109