2015-04-03 61 views
0
1. void* x; 
2. x = new int [10]; 
3. x = static_cast<int*>(x); 
4. *x = 2; 

第4行中,我得到:error: ‘void*’ is not a pointer-to-object type如何將一個void指針轉換爲一個int指針,然後在其中存儲一個int?

+0

**不要**用C++中的'void *'操作!這是出了名的錯誤,容易違反嚴格的別名規則(並因此引起未定義的行爲)。 – Walter 2015-04-03 10:25:11

+1

C++是靜態類型的。這意味着'x'的類型被確定爲編譯時間。它的值可能會在運行時改變,但它永遠是一個'void *' - 即使你指定了一個'int *'。這就是爲什麼您在賦值中進行類型轉換的原因,原因正是因爲您無法更改目標的類型以匹配源。 – MSalters 2015-04-03 10:59:55

+0

@Walter據我所知,在嚴格的別名規則中,void *和char *類型應該有例外。否則像memset這樣的東西就無法工作。 – dewaffled 2015-04-03 11:40:51

回答

3

您需要定義新的指​​針類型。

您靜態鑄造x,但類型信息在靜態轉換後丟失,因爲在聲明時x是void *。

x在他整個一生中都會堅持無效*。

這裏的工作代碼示例:

 void* x; 
    int* ptr; 
    x = new int[10]; 
    ptr = static_cast<int*>(x); 
    *ptr = 2; 

OR alternativelly,您可以ASIGN及演員在同一行:

*(static_cast<int*>(x)) = 2; 
+0

我認爲這違反了嚴格的別名規則,因此羨慕UB。 – Walter 2015-04-03 10:26:09

+0

@Walter是和否。 NO,因爲指針指向的類型是int且具有sizeof(int),並且在分配和寫入時由int類型引用。所以這個確切的代碼片段是好的。是的,因爲這種編碼很容易讓你違反規則(基本上使用void *來保持指針類似於重新演繹遍佈整個地方)...... – MichaelCMS 2015-04-03 10:33:06

+2

@Walter:沒有別名;這是一個'int *'指針指向一個'int'數組。這樣的神經網絡很容易導致混淆違規,因爲沒有類型檢查,但這裏沒有,因爲儘管沒有被檢查,類型是正確的。 – 2015-04-03 10:35:37

0

由於任何指針(除成員指針和指向功能,這是完全別的東西)可以隱式轉換爲空指針,您的第2行將new int[10]的結果隱含地從int *轉換爲void *

同樣,您的線路3明確地轉換到xint *(所述static_cast)和該結果被隱式轉換回和存儲在x。這沒有任何實際效果。如果編譯器足夠聰明,它會完全忽略該語句。

你需要做的是引入另一個變量,它是指向int的指針。

void *x; 
x = new int[10]; 
int *y = static_cast<int *>(x); 
*y = 2; 

如果你確實想使用一個沒有任何int指針的變量的void指針,

void *x; 
x = new int[10]; 
*(static_cast<int *>(x)) = 2; 

這是非常醜陋的,只在特殊情況下需要。

實際上,除非你需要特別指定其他東西的void指針,否則完全消除它。

int *x; 
x = new int[10]; 
*x = 2; 

,沒有必要與任何顯式類型轉換的猴子身邊的事實使得這種不容易出錯了。

+0

我認爲這違反了嚴格的別名規則,因此嫉妒UB。 – Walter 2015-04-03 10:28:27

+0

你覺得不對。唯一的解引用是int *(隱式或顯式地)訪問動態分配的int數組的元素。沒有類型的搗蛋正在進行。 – Peter 2015-04-03 10:36:08

相關問題