Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从函数返回将上下文更改为NULL_C++_Visual C++_Visual Studio Debugging_Visual Studio 2015 - Fatal编程技术网

C++ 从函数返回将上下文更改为NULL

C++ 从函数返回将上下文更改为NULL,c++,visual-c++,visual-studio-debugging,visual-studio-2015,C++,Visual C++,Visual Studio Debugging,Visual Studio 2015,我有三门课与这个问题有关。我正在为一个应用程序实现一个硬件服务。PAPI(平台API)是一个硬件服务类,用于跟踪各种硬件接口。我实现了一个抽象的HardwareInterface类,以及一个派生它的类HardwareWinUSB 下面是与我所做的类似的例子。我遗漏了似乎与此问题无关的成员,例如打开USB连接的功能: class PAPI { HardwareInterface *m_pHardware; PAPI() { m_pHardware = new Ha

我有三门课与这个问题有关。我正在为一个应用程序实现一个硬件服务。PAPI(平台API)是一个硬件服务类,用于跟踪各种硬件接口。我实现了一个抽象的HardwareInterface类,以及一个派生它的类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
在0xC0000005:执行位置0x00000000中的0x00000000处引发异常
如果我深入研究PAPI密码,我会看到奇怪的行为。 当我在WritePacket的主体中设置断点时,一切看起来都正常。然后,我在调试器中执行“跨步”。函数调用返回后,我对“this”的引用设置为0x00000000

发生了什么事?似乎在返回堆栈上推送了空值?以前有人见过这样的事吗?我是否错误地使用了虚拟方法

编辑
在进一步剖析之后,我发现在调用write之前我正在读取,并且我正在读取的缓冲区是在本地范围内声明的。当新的读取进入时,它们被推入堆栈中,破坏了堆栈。下一个名为write的函数将返回到一个已销毁的堆栈。

缓冲区溢出会将堆栈上的返回地址丢弃。您似乎正在使用空指针读写数据包,并且没有传递显式大小,因此很可能出现一个简单的溢出错误。VisualStudio编译器可以选择添加堆栈完整性检查来检测这些类型的bug,但它们并不是100%完美的。尽管如此,请确保已将其打开


还请注意,Visual Studio调试器有时(但很少)会为
this
显示错误的值,特别是在您尝试调试优化代码时。如果您在方法末尾的
}
,我不必担心调试器显示
this

的奇异值。进一步剖析后,我发现在调用write之前我正在读取,并且我正在读取的缓冲区是在本地范围内声明的(在read函数中)


当新的读取进入时,它们被推入堆栈中,破坏了堆栈。我调用的下一个函数write将返回到一个已销毁的堆栈。

发生的是代码中的某个错误。一个常见的花园品种错误的结果是“未定义的行为”,你可以观察到的结果肯定是合格的。你只需要找出你的bug是什么。不幸的是,目前还没有按数字绘制的方法来找出并追踪这个bug。如果有,我就失业了…谢谢你的回复,山姆。我知道这是一个bug。我在C++中已经工作了大约三年,还没有看到这样的问题:返回堆栈会像这样被破坏。我希望得到比我更有经验的人的提示,而不是“你的问题是你有问题。”谢谢你的回答,阿德里安。我也有同样的想法,这可能是由缓冲区溢出引起的。所以我检验了这个假设。为此,我将void*参数替换为uint8_t(&Buffer)[PACKET_SIZE],其中PACKET_SIZE是一个定义的常量。这迫使我的代码总是传递特定大小的缓冲区。不幸的是,这似乎没有改变任何事情。我看了一下我复制和设置内存的地方,它们看起来很好。你认为我看到这一点还有其他原因吗?谢谢你在这里分享你的解决方案。如果可能,请将您的回复标记为答案,以便帮助其他社区成员。祝你今天愉快:)