2017-01-09 63 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)您试图将数据输入缓冲区,该缓冲区将像素置于屏幕之外。