C ++中的Bizzare nullref

增强现实

我有一小段C ++代码让我发疯。每当它运行时,它都会在一个非常意外的地方引发空引用异常。

void CSoundHandle::SetTarget(CSound* sound)
{
  assert(_Target == nullptr);
  if (sound == nullptr) { return; }

  _Target = sound;

  // This works just fine.
  _Target->Play();

  // This is the code that throws the exception.  It doesn't seem possible, as
  // we should not be able to get here if 'sound' is null.
  _Target->Stop();
}

那么到底发生了什么?输出窗口中的消息是:

this->_Target-> was nullptr.
0xC0000005: Access violation reading location 0x00000014

我已经在反汇编中确认,它也不会在Stop函数内部发生。这怎么可能?

编辑:声音的指针确实已初始化,并且'this'和'this-> Target'为非null。

编辑2:通过某种方式稍微更改Stop函数的声明,我已经以某种方式解决了该问题:

// From this.
virtual void Stop();

// To this.
void Stop();

这似乎特别奇怪,因为Play()也是虚拟的,但是可以正常工作。我不能说我以前见过这样的东西。在程序的其余部分中没有其他名为“ Stop”的函数,也没有CSound的子类,所以我有点困惑。

他们是

读取位置0x00000014意味着您正在尝试访问一个距离对象开头0x14字节的字段。指向该对象的指针设置为null。因此问题出在函数的调用者中:它向传递了错误的指针sound,该指针既不为null也不有效。这就是为什么函数中的null检查通过(0x14不为null)但仍然崩溃的原因。

更新:对该问题的第二次编辑表明该问题出在调用虚函数上。空值是虚拟指针,0x14是Stop虚拟函数的偏移量虚拟指针是在对象构造过程中设置的(由编译器生成的代码),并且永远不要指向0。如果这样做,则表明程序的某些部分正在破坏对象。一种易于检测的情况是尝试重置对象,但是内存损坏(例如,对数组的越界写入)也可能导致此问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章