今天在編寫一系列新增需求代碼后,開始調試代碼
發現上個版本正常可運行的代碼出現了:引發的異常: 0xC0000005: 讀取位置 0xFFFFFFFFFFFFFFFF 時發生訪問沖突。
上個版本數代碼明明是沒有問題的,怎么就突然出現這個問題了呢?
一般來說這個問題是由於引用了空指針、數組越界,使用了野指針等問題,
然后檢查了運行相關代碼,並未發現問題。
進入逐步調試:
發現有一個類里面的數據發生讀取內存異常,調試器里出現地址大小端紊亂:
有的地址是正常的大端地址:0x000000000034fa48(正常)
然而二級指針地址出現小端地址:0x0034fa4000000000(錯誤),這個地址是無法讀取內存的,已越過計算機個該程序分配的內存上線,而在0x000000000034fa40這個位置讀取的內存數據卻是正常的。
經過各種尋找,嘗試網上各種可能解決問題的方法,還是未解決。
由於上個版本是能夠運行,這個版本就出現異常,然后我就對比兩個版本差異
發現引用了一個頭文件,該頭文件的#pragma pack使用錯誤,
頭文件 開頭我是這樣寫的:#pragma pack(1)
頭文件 末尾我是這樣寫的:#pragma pack(pop)
然后發現編譯器報的warring 如下:
(很多時候我們都不看 warring, 但是很多時候你忽略的warring往往給你帶來大麻煩)
我去查詢了下 pragma pack的用法:
pragma pack(1),這種是我自定義我的對齊方式為1,而沒有入棧操作(這里的棧是the internal compiler stack)
而pragma pack(pop), 是這樣操作的:從internal compiler stack中刪除最頂端的record;如果沒有指定n,則當前棧頂record即為新的packing alignment數值;
如果指定了n,則n將成為新的packing aligment數值;如果指定了identifier,則internal compiler stack中的record都將被pop直到identifier被找到,然后pop出identitier,
同時設置packing alignment數值為當前棧頂的record;如果指定的identifier並不存在於internal compiler stack,則pop操作被忽略
我這里就是制定了自定義對齊值為1, 當執行pop操作時候,則用我的自定義值(1)作為對齊方式, 而棧中找不到這個數據,則出現出棧比入棧多的warring
但是為什么對齊方式沒有使用8,會導致 調試器二級指針出現地址大小端紊亂(實際程序也紊亂了)問題,這里還不知具體原因