2016-02-27 321 views
2

需要將數組從unsigned char *安全地轉換爲char *。 我這樣做。它是否正確?將數組從unsigned char *轉換爲char *

std::vector < unsigned char > arr; 
char *imgData = (char*) malloc(arr.size()); 
for (int i = 0; i < arr.size(); i++) imgData[ i ] = (arr.at(i) - 128); 
+0

「安全轉換」是什麼意思? – ixSci

回答

3

不,這是不安全的。或者更重要的是,它在C++中不是定義明確的行爲。

char允許簽名或簽名,但是實現認爲合適。如果char是無符號的,則從unsigned char減去128將會截斷一半的位。如果char已簽名,則不能保證它是二進制補碼,因此減去128將不會達到您想要的值。

那種你正在試圖做的轉換是不合理的。您將變量命名爲imgData,因此您似乎打算將該數據發送給某個圖像API。並且該API需要經常使用char。所以你的目標似乎是將每個unsigned char轉換爲char,它們共享原始unsigned char的完全相同的位模式。

在這種情況下...只是轉換指針:static_cast<char*>(arr.data())。你會以任何方式挑起未定義的行爲;我寧願這樣做可能實際上工作;)

此外,應該指出,C++ 14使其實際上不可能實現char的簽名版本,不使用二進制補碼。這是因爲需要通過可能簽名的char類型來支持UTF-8。您必須能夠將char*轉換爲unsigned char*並返回,以便保留所有有效UTF-8代碼單元的位模式。

所以劇組仍然是最有可能做的其實你想要的選項。

+0

爲什麼將'unsigned char *'轉換爲'char *'會引起UB? – ixSci

+1

@ixSci:這不是轉換;這是訪問。據推測,無論是接收'imgData'的人都會從中讀取或者將其作爲char *寫入。如果他們這樣做,那麼它就是UB。如果他們在讀取之前將其轉回到'unsigned char *',那麼它將被明確定義。 –

+0

雖然我知道如何通過'char *'寫入'unsigned char *'數據可能會弄亂一切,我不明白爲什麼你說從這個轉換的指針讀取的數據也是UB。它不會讀取從相應的uchars轉換而來的明確定義的字符嗎? – ixSci

相關問題