1

我有三個與此問題相關的類。我正在爲應用程序實施硬件服務。 PAPI(平臺API)是一個硬件服務類,用於跟蹤各種硬件接口。我實現了一個抽象的HardwareInterface類和一個派生它的類HardwareWinUSB。從函數返回將上下文更改爲NULL

下面是與我所做的相似的例子。我已經離開了,不會出現要與這一問題有關,類似的功能,打開USB連接件:

class PAPI { 
    HardwareInterface *m_pHardware; 

    PAPI() { 
     m_pHardware = new HardwareWinUSB(); 
    } 

    ~PAPI() { 
     delete m_pHardware; 
    } 

    ERROR_CODE WritePacket(void* WriteBuf) 
    { 
     return m_pHardware->write(WriteBuf); 
    } 
}; 

class HardwareInterface { 
    virtual ERROR_CODE write(void* WriteBuf) = 0; 
}; 

class HardwareWinUSB : public HardwareInterface 
{ 
    ERROR_CODE write(void* Params) 
    { 
     // Some USB writing code. 
     // This had worked just fine before attempting to refactor 
     // Into this more sustainable hardware management scheme 
    { 
}; 

我一直是這樣,現在冥思苦想了好幾個小時。這是一個奇怪的,可重複的問題,但有時是間歇性的。如果我在更高的上下文中遍歷調試器,則執行得很好。如果我不深挖不夠,我會見了讀取

Exception thrown at 0x00000000 in <ProjectName.exe>: 0xC0000005: Access violation executing location 0x00000000 

如果我挖下到PAPI代碼,我看到了怪異的行爲的錯誤。 當我在WritePacket的主體中設置斷點時,一切顯示正常。然後我在調試器中進行「一步一步」。從函數調用返回後,我對「this」的引用設置爲0x00000000。

這是怎麼回事?它看起來像一個空值被推入返回棧?有沒有人看過類似的事情發生過?我是否錯誤地使用虛擬方法?

編輯 進一步解剖後,我發現我打電話之前寫讀,我是讀入本地範圍內被宣佈爲緩衝區。當新閱讀進來時,他們被推入堆棧,破壞它。下一個稱爲write的函數將返回到已銷燬的堆棧。

+0

發生什麼事是你的代碼中的某個地方發生了錯誤。一個共同的,花園多樣的錯誤的結果是「未定義的行爲」,其中你可觀察到的結果肯定有資格。你只需要弄清楚你的bug是什麼。不幸的是,沒有按照數字來繪製和追蹤錯誤的方法。如果有,我會失業... –

+0

謝謝你的迴應,山姆。我明白這是一個錯誤。我一直在C++專業工作三年左右,並且還沒有看到返回堆棧像這樣被損壞的問題。我希望得到比我更有經驗的人的暗示,而不是「你的問題是你有問題。」 – Michael

回答

0

經過進一步解剖之後,我發現在調用write之前我正在讀取,並且正在讀取的緩衝區在局部範圍內(在read函數中)聲明。

當新讀取進來時,它們被推入堆棧,破壞它。我調用的下一個函數write將返回到被銷燬的堆棧。

+0

感謝您在這裏分享您的解決方案。如果可能的話,也請將您的答覆標記爲答案,這樣可以幫助其他社區成員。祝你今天愉快:) –

1

緩衝區溢出可能會破壞堆棧上的返回地址。你似乎在讀取和寫入帶有空指針的數據包,並且沒有傳遞明確的大小,所以一個簡單的超限錯誤看起來很可能。 Visual Studio編譯器有添加堆棧完整性檢查以檢測這些類型的錯誤的選項,但它們不是100%完美的。儘管如此,請確保您已將其開啓。

另請注意,Visual Studio調試器偶爾(但很少)會顯示this的錯誤值,特別是在您嘗試調試優化代碼時。如果您在方法結束時位於},我不一定擔心調試器會顯示this的奇怪值。

+0

感謝您的迴應,Adrian。我有同樣的想法,這可能是由緩衝區溢出引起的。所以我測試了這個假設。爲此,我用uint8_t(&Buffer)[PACKET_SIZE]替換了void *參數,其中PACKET_SIZE是一個定義的常量。這迫使我的代碼總是傳遞特定大小的緩衝區。不幸的是,這似乎沒有改變任何事情。我看着我複製和設置記憶的點,他們看起來很好。你認爲我還能看到這個嗎? – Michael