2013-12-08 37 views
2

爲了自我充實,我正在構建一個小型鏈表庫,這迫使我處理一個我幾乎無法解釋的問題。看看下面的例子,並假定new_item->data是typedef結構內的空指針:從void指針獲取int的問題

int *data = malloc(sizeof(int)); 
*data = 42; 
MY_LIST *new_item = malloc(sizeof(*new_item)); 
new_item->data = &data; 

// prints what looks like a memory address 
printf(
    "data: %i\n", 
    *((int *) new_item->data) 
); 

//prints 42 
int data2 = *((int *) new_item->data); 
printf(
    "data2: %i\n", 
    *((int *) data2) 
); 

至於我(可能是廢棄的)大腦所知道的,在這兩種情況下我使用同樣的鑄造聲明 - *((int *) new_item->data) - 從它的容器派生整數。然而,當我在printf內部使用它時,我得到了一個內存地址。我對此有什麼誤解?

+0

歡迎來到指針地獄。 –

+1

調整你的_data_賦值爲'new_item-> data = data;' – amdixon

+0

不應該'MY_LIST * new_item = malloc(sizeof(* new_item));'是'MY_LIST * new_item = malloc(sizeof(new_item));'? 'sizeof(new_item)',而不是'sizeof(* new_item)'? –

回答

2

這是問題所在。

new_item->data = &data; 

data指向指針的地址(指針指針)。 data已經是一個指針了。

讓它以下

new_item->data = data; 

在下列情況下

//prints 42 
int data2 = *((int *) new_item->data); 
printf(
    "data2: %i\n", 
    *((int *) data2) //You are dereferencing the pointer, 
); 

您提領,這就是爲什麼它打印42

在這種情況下,指針

// prints what looks like a memory address 
printf(
    "data: %i\n", 
    *((int *) new_item->data) 
); 

您正在刪除存儲在new_item->data中的&data,它現在指向data。這就是它打印地址的原因。得到42,再解除它。

+0

但我也取消引用第一種情況下的指針! –

+0

很好的引用,雖然...我甚至不知道爲什麼我首先做到了這一點。這支部隊今晚不在我身邊。 –

+0

請參閱編輯。 – doptimusprime