2011-10-17 81 views
3

我正在爲一個ipad程序編寫一個文件加載器,並且出現了奇怪的EXC_BAD_ACCESS異常。這裏是簡短的代碼文檔片斷,我認爲是錯誤的原因:EXC_BAD_ACCESS和char指針指向浮動指針

float testFloat() { 
    char mem[32]; 
    char *charPtr = &mem[0]; 
    float *floatPtr = (float*)(charPtr + 1); 
    float f = *floatPtr; //EXC_BAD_ACCESS 
    return f; 
} 

發生誤差僅在charPtr偏移不被4整除,所以我想它可能有一些做與指針在ARM CPU上對齊。

回答

7

你是對的,這是由於指針對齊。在許多RISC系統中,對齊需要至少與數據類型本身一樣大。 (ARM屬於這一類。)

在這種情況下,float是4個字節,所以地址需要對齊到4個字節。 (可被4整除)

此外,這種類型的竄改違反了嚴格別名。

在x86系統上,內存訪問並不總是必須對齊 - 但通常會導致訪問不對齊時的性能損失。

+2

'字符*'和'無符號字符*'是從嚴格走樣規則相容,因此這段特定的代碼不會違反它。 – ildjarn

+0

@ildjarn:你說得對。我忘了你可以用'char'替代別名。將修復答案。 – Mysticial

+0

謝謝,我會用一些memcpy的。我仍然覺得這個錯誤有點奇怪,是不是編譯器有義務爲這個剪輯生成工作二進制文件?或者它違反了一些規則? –

-1

如何

struct MyStruct 
{ 
char* _charPtr; 
float* _floatPtr; 
}; 

MyStruct myStruct = &mem[0]; 

float f = *(myStruct._floatPtr); 

難道違反指針對齊要求?
不確定,但值得一試。

+1

這甚至沒有編譯。你的意思是'union'而不是struct嗎?即使你做了這個改變,它仍然不能編譯。 –

2

發生這種情況是由於內存不對齊。 手臂處理器有問題。

發現這個解決方案, http://www.cocos2d-x.org/forums/6/topics/18183

而不是

float *floatPtr = (float*)(charPtr + 1); 
float f = *floatPtr; //EXC_BAD_ACCESS 
return f; 

使用

float f; 
unsigned char* pData = (charPtr + 1); 
memcpy(&f, pData, sizeof(float));