当我运行我的代码时,我得到了这个错误"在赋值的0x00042DE0处的未处理异常2.exe:0xC0000005:访问冲突写入位置0x00000000。"
在类中调用函数时会发生这种情况 我的代码如下(如果我错过了重要的事情,请告诉我)
答案 0 :(得分:0)
在
BouncingBall::BouncingBall()
{
Initialise(0, 0, 0, 0, 0);
m_pRenderer = NULL;
}
m_pRenderer
显式为NULL。它没有分配存储空间。
然而,这看起来应该在
中得到纠正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 NULL if (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
}
}
答案 1 :(得分:0)
根据我的经验,导致此错误的原因有两个:
1)您试图使用无效的指针调用函数。
2)您试图将数据输入缓冲区,将数据放在屏幕外。