2010-12-07 193 views
3

編輯:錯誤的num2類型已被更正。將字符數組轉換爲整數

您好,

我有一個包含從一個二進制文件中讀取原始整數數據已知大小的一些字符陣列。

所有這些數組的大小都有一個整數的大小。

我想問問以下操作在所有正常情況下是否安全準確,假設原始數據的末端性和運行此代碼的計算機一致。

char arr1[4] = { ... }; 
char arr2[2] = { ... }; 

uint32_t num1 = *static_cast<uint32_t*>(arr1); /* OR num1 = *(uint32_t*)arr1 in C */ 
uint16_t num2 = *static_cast<uint16_t*>(arr2); /* OR num2 = *(uint32_t*)arr2 in C */ 

謝謝!

+3

既然它是一個二進制文件,你最好將原始整數讀入一個整數數組。 – chrisaycock 2010-12-07 19:19:56

+1

不要一次聲明多個變量。它可能導致微妙的錯誤。 https://www.securecoding.cert.org/confluence/display/seccode/DCL04-C.+Do+not+declare+more+than+one+variable+per+declaration – 2010-12-07 19:23:22

+0

直接將字符內存轉換爲一個整數只能工作在字節對齊的CPU上,而不是字對齊。如果你只是/總是在Intel x86上運行,那不會是一個問題。 – 2010-12-07 19:36:26

回答

3

這在技術上是安全的,但也有幾件事情我會考慮:

  • 添加編譯時斷言,以驗證大小。你是否確定你的char數組等於sizeof(your_int_type)?您的num2就是一個很好的例子,說明這很重要 - 您的錯字會導致未定義的行爲。
  • 考慮對齊。你確定你的char數組是在一個4字節的邊界上(假設你的int是4個字節)?例如,如果您嘗試從未對齊的指針讀取一個int,PowerPC會崩潰。
1

這應該是安全的:

char arr1[4] = { ... }; 

uint32_t num1; 

memcpy(&num1, arr1, sizeof num1); 

但爲什麼只有arr2 2個字節大?這是一個錯字嗎?

0

更安全的方法是使用宏(例如MAKEDWORD)將字節按正確順序排列。

0

如果你確定數組是正確對齊的,那麼應該沒有問題(給定字節序)。

然而,在代碼中,我不知道你在做什麼,因爲它是16位,而你正在讀取一個32位的數量。

0

是的,這應該可以正常工作(在您假定的字節順序下),因爲這些字節在內存中的表示是相同的,無論它是解釋爲字節數組還是整數。

真的,你所做的只是改變類型而不是數據。

5

您應該使用聯合。

union charint32 { 
    char arr1[4]; 
    uint32_t num; 
}; 

這會爲您簡化存儲和投射。