从功能返回将上下文更改为null

Returning from Function changes context to NULL

本文关键字:null 上下文 功能 返回      更新时间:2023-10-16

我有三个与此问题相关的类。我正在为应用程序实施硬件服务。Papi(Platform API)是一个硬件服务类,可以跟踪各种硬件接口。我已经实现了一个抽象的硬件界面类,并将其派生称为HardwareWinusB。

以下是类似于我所做的示例。我遗漏了似乎与此问题无关的成员,例如打开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代码,我会看到奇怪的行为。当我在写入Packet的正文中设置一个断点时,一切似乎正常。然后,我在调试器中做了"一步"。从函数调用返回后,我对"此"的引用设置为0x00000000。

发生了什么事?似乎在返回堆栈上推动了无效的值?有没有人看过这样的事情?我是否错误地使用虚拟方法?

编辑进一步解剖后,我发现我在打电话给写作之前正在阅读,而我正在阅读的缓冲区则在当地范围内宣布。当新的阅读进来时,他们被推入堆栈,破坏它。下一个称为"写"的功能将返回被破坏的堆栈。

缓冲区跨越可以丢弃堆栈上的返回地址。您似乎正在阅读和编写带有无效指针的数据包,而无需透露明确的大小,因此一个简单的超支错误似乎很可能。Visual Studio编译器具有添加堆栈完整性检查以检测这些错误的选项,但它们并不是100%完美的。尽管如此,请确保您已打开它们。

还要注意,Visual Studio调试器偶尔会(但很少)显示this的错误值,尤其是在您尝试调试优化代码时。如果您在方法末尾处于},我不一定会担心调试器显示this的奇异值。

进一步解剖后,我发现我在打电话写之前正在阅读,而我正在阅读的缓冲区则在本地范围(在读取功能中)声明。

当新的阅读进来时,它们被推入烟囱,破坏了它。我致电,写的下一个功能将返回被破坏的堆栈。