2017-01-09 60 views
-1

即時嘗試做一個簡單的乒乓球遊戲的學校課程和即時貼卡住我的教程。C++錯誤創建乒乓球遊戲

當我運行我的代碼時,出現此錯誤「賦值2.exe 0x00042DE0未處理的異常:0xC0000005:訪問衝突寫入位置0x00000000」。

調用類中的一種功能,當 我的代碼如下它發生(讓我知道如果我錯過了一些重要的東西)

+1

您是否嘗試在調試程序中檢查變量值的同時單步執行代碼? –

+1

「C++錯誤我不知道如何解決」在這裏是一個相當常見的問題。推薦一個更具描述性的標題。 – user4581301

+1

「訪問衝突寫入位置0x00000000」。當訪問對象的第一個成員時,建議'this'是一個NULL指針。不能說更多,或建議一個解決方案,沒有[mcve] – user4581301

回答

0

BouncingBall::BouncingBall() 
{ 
Initialise(0, 0, 0, 0, 0); 
m_pRenderer = NULL; 
} 

m_pRenderer明確清零。它沒有分配存儲空間。

但是這看起來像它應該在

void BouncingBall::Initialise(int m_PositionX, int m_PositionY, int m_DirectionX, int m_DirectionY, ASCIIRenderer* m_pRenderer){ 


} 

予以糾正,但BouncingBall::Initialise還沒有得到充分執行,並丟棄所提供的渲染器。 m_pRenderer仍然是NULL。

void BouncingBall::Render() 
{ 
if (m_pRenderer == NULL){ 
    CHAR_INFO ball; 
    ball.Char.AsciiChar = 0; 
    ball.Attributes = BACKGROUND_RED; 
    m_pRenderer->SetPixel(m_PositionX, m_PositionY, ball); 
    } 
} 

m_pRenderer後來的測試,以確保它仍然指向不惜一切代價,然後調用。這與邏輯OP需求相反,並且在NULL指針上調用SetPixel。繁榮。

解決方案:全面貫徹BouncingBall::Initialise並更換試驗BouncingBall::Render用於爲NULL if (m_pRenderer == NULL)與是NOT NULLif (m_pRenderer != NULL)

雖然一個更好的方法就是擁抱RAII並沒有擺在首位的初始化函數。在構造函數中執行。在構造函數中測試有效的渲染器,如果無效,則拋出異常以中止構造。

這種方式總是有一個有效的渲染器,如果有一個對象,如果不是NULL檢查是不必要的。

編輯:

全面實施BouncingBall::Initialise

void BouncingBall::Initialise(int PositionX, 
           int PositionY, 
           int DirectionX, 
           int DirectionY, 
           ASCIIRenderer* pRenderer){ 
    m_PositionX = PositionX; 
    m_PositionY = PositionY; 
    m_DirectionX = DirectionX; 
    m_DirectionY = DirectionY; 
    m_pRenderer = pRenderer; 
} 

注意參數的名稱更改爲不匹配的成員變量。

但是......

RAII(Resource acquisition is initialization)建議您不要使用BouncingBall::Initialise功能,而是採取構造函數的優勢

void BouncingBall::BouncingBall(int PositionX, 
           int PositionY, 
           int DirectionX, 
           int DirectionY, 
           ASCIIRenderer* pRenderer) : // Member Initializer List 
    m_pRenderer(pRenderer), 
    m_PositionX(PositionX), 
    m_PositionY(PositionY), 
    m_DirectionX(DirectionX), 
    m_DirectionY(DirectionY) 
{ 
    if (m_pRenderer == NULL) 
    { 
     // throw exception here. This will prevent having an improperly 
     // initialized BouncingBall acting as a ticking timebomb. 
     // the constructed object will be politely destroyed as if it never existed 
    } 
} 

Documentation on Member initializer list.

+0

非常感謝!但很抱歉,如果它的愚蠢,我如何完全實現bouncingBall :: Initialise ?? –

+0

@JackC void BouncingBall :: Initialise(int m_PositionX,int m_PositionY,...)中的變量與定義爲類成員的變量不同(即int m_PositionX; int m_PositionY; ...),即使它們具有相同的名稱。它們是不同的,具有相同名稱的臨時變量。您必須將這些臨時變量分配給成員變量,以使它們保持不變。因爲它們具有相同的名稱,所以不能簡單地使用'm_PositionX = m_PositionX;',因爲這看起來像是一個自賦值。任何優秀的編程文本都會告訴你如何避免這種情況或徹底避免它。 – user4581301

+0

非常感謝你任何機會,你可以告訴我在哪裏閱讀這些文本:) –

0

根據我的經驗,有過兩次導致此錯誤:

1)您試圖調用一個函數與指針是inval ID。

2)您試圖將數據輸入緩衝區,該緩衝區將像素置於屏幕之外。