2014-05-09 47 views
0

我需要了解爲什麼分配void*int**將起作用,但是當打印int**的值時,它將不起作用。下面的代碼:分配空白到雙指針

int k = 3; 
int *l = &k; 
void *a = l; 
int **c = a; // if I assign, &a, the below line work, but get warning: incompatible 
      // pointer type. 
printf("%d", **c); // Code break; 

,但此行

printf("%d", *c); // will work, but get warning "%d expect int but of type int *". 

更新:我看到這種類型的代碼在OOC book這裏筆者做:

struct Class { 
    size_t size; 
    int (*differ)(const void *self, const void *b); 
    ..... Some more code .... 

}; 

int differ(const void *self, const void *b) { 
    // Note this line 
    const struct Class **cp = self; 
    assert(self && *cp && (*cp)->differ); 
    return (*cp)->differ(self, b); 
} 
+4

** c將嘗試讀取地址'3'中的整數 – Bgie

回答

3

你有這樣的情況:

 
+---+ 
| l | --\ 
+---+ \  +---+ 
      >--> | k | 
+---+ / +---+ 
| a | --/ 
+---+ 

la都直接指向k

當你那麼做

int **c = a; 

你讓c點什麼a指向以及(即它一樣做int **c = &k),但你申報c是要指向一個int指針,但請直接指向int。這意味着使用單個解除引用(*c)得到值k,並且當您使用雙引用(**c)時,將k的值用作指針(它不是)。

我假設你真正想要的是這種情況:

 
+---+  +---+  +---+ 
| a | --> | l | --> | k | 
+---+  +---+  +---+ 

,你將通過然後使用c爲指針,以指針會工作,因爲再a

void *a = &l; 

得到的是一個指針到一個指針。


如果繼續與第一種情況,那就是你有

int k; 
int *l = &k; 
void *a = l; 

,然後做

int **c = (int **) &a; // The typecast is needed 

那麼你有以下情況:

 
      +---+ 
      | l | --\ 
      +---+ \  +---+ 
        >--> | k | 
+---+  +---+ / +---+ 
| c | --> | a | --/ 
+---+  +---+ 

這將因爲那麼工作c真的是指向某物的指針。

+0

你最後一行'void * a =&l'。如果我使用這個,那麼我必須使用'int ** c = a',這會起作用。但請參閱'c'分配'a'不是a'的地址。你能說明一下嗎? –

+0

@ ashish2expert更新了我的回答,查看結尾。 –

+0

因爲'&l'的類型是'(int **)'而'a'是'void *',所以'void * a =&l;'不是'void * a =&l; –

2

這就是爲什麼你必須要小心void*指針。您可以指定任意指針指向它們,並且您可以將它們指定給任何其他指針。即使它沒有意義(就像你的例子)。

當您指定int **c = a時,您犯了一個錯誤,我認爲您已經知道。您已更改間接性級別(a來自int*,但您將其分配給int**),但未採用另一個地址(即&)。

由於相同的原因,如果您刪除了void* a,而您嘗試這樣做,則程序將失敗。

int k = 3; 
int *l = &k; 
int **c = l; // Error - wrong level of indirection. 

這是低級別的C.只是因爲編譯器讓你做某件事並不意味着它會起作用。

此問題的解決方案是:不要這樣做

+0

我在'OOC book'中看到了這種類型的代碼,在該書中,作者將'void * self'賦值給'struct Class ** cp = self'。 –

+0

@ ashish2expert需要更多的上下文才能有意義。 –

+0

好吧,我會更新代碼 –