1. 程式人生 > >好詭異,void*指標強轉後發生詭異偏移

好詭異,void*指標強轉後發生詭異偏移

先上程式碼,作業系統centos6.5,gcc版本4.4.7 20120313,純C程式碼

int EvoSdtpImsiMIExt(void *arg, void *user)
{
    (void)user;
    EvoCallInfo *evi = (EvoCallInfo *)arg;
    uint32_t imsi_len   = EvoSdtpFieldsGetBCD(evi, 0, imsi);
}

EvoCallInfo是一個自定義的結構體,在外部malloc了一塊記憶體,通過void指標進行函式傳遞,在EvoSdtpImsiMIExt再強轉回EvoCallInfo

,然後再用該指標呼叫EvoSdtpFieldsGetBCD函式,然後在EvoSdtpFieldsGetBCD中使用該結構。
那麼問題來啦
在EvoSdtpFieldsGetBCD函式中一呼叫EvoCallInfo指標程式就掛掉了
然後定位了問題產生的原因,問題出現在EvoCallInfo evi = (EvoCallInfo )arg;這一句上,將void型別的arg指標強專成EvoCallInfo型別的evi時,指標變數值發生詭異的位移,每次都向前位移了0x50個位元組
下圖是gdb除錯資訊,堆疊位於EvoSdtpImsiMIExt函式
在這裡插入圖片描述

在EvoSdtpFieldsGetBCD堆疊中,如果使用函式傳進來的指標程式就掛掉,強行檢視正確地址記憶體資料並沒有問題
下圖是gdb除錯資訊,堆疊位於EvoSdtpFieldsGetBCD函式
在這裡插入圖片描述

變數evi和eci有一個錯誤輸入,大家忽略這個細節

如果不用中間變數中轉,直接使用arg呼叫函式就沒問題,下面是可以執行的程式碼

int EvoSdtpImsiMIExt(void *arg, void *user)
{
    (void)user;
    uint32_t imsi_len   = EvoSdtpFieldsGetBCD((EvoCallInfo *)arg, 0, imsi);
}

一直想不通為什麼會產生這個bug,指標在進行強轉的時候還會發生偏移?大家有沒有遇到過類似的問題?請大家幫忙分析一下問題產生的原因