2013-12-08 51 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