我尝试访问win32应用程序中的空指针值,但没有发生访问冲突

I try to access the value of a null pointer in win32 application, but no access violation occurs

本文关键字:访问冲突 空指针 访问 win32 应用程序      更新时间:2023-10-16

我编写的示例代码应该会导致访问冲突,但事实并非如此。我认为return *m_pObjGetSession1()GetSession2()函数中应该出现异常,但事实并非如此。为什么?

头文件

class CSession
{
    public:
        CSession() {};
        ~CSession() {};
        CSession(const CSession& rhs) {};
    private:
        long m_lUSN;
};
class CTest
{
    public:
        CSession* m_pObj;
        CSession& GetSesstion1() { m_pObj = NULL; return *m_pObj; }
        CSession GetSesstion2(); { m_pObj = NULL; return *m_pObj; }
};

Cpp文件

int _tmain(int argc, _TCHAR* argv[])
{
    CTest test;
    CSession Session2 = test.GetSesstion1();
    CSession Session3 = test.GetSesstion2();
    return 0;
};

取消引用空指针是未定义的行为(这里有一个更"严重"的链接:为什么取消引用空指示器是未定义行为?)。你的程序可能会崩溃,或者随心所欲。C++标准没有强制要求存在"访问冲突"。

未定义行为(UB)是坏的,你不能总是依赖编译器来捕捉它。例如,下面的代码清楚地说明了UB坏的原因:

#include <iostream>
int main()
{
    int *p = nullptr;
    int  q = *p;
    //std::cout << q;
}

在我的机器上,我没有得到任何警告,代码编译和运行都很好。如果我取消对std::cout行的注释,BANG,它就会崩溃。这可能是因为编译器优化了空指针的去引用,但在尝试使用q时无法优化它。这可能是你的代码中发生的事情,但同样,这是UB,程序运行的事实不应该给你任何保证。

您编写的构造函数不执行任何操作,因此当位于NULL地址时,实际上并没有尝试访问m_lUSN,因此不会获得任何AV。如果您更改CSession()复制构造函数以将rhs.m_lUSN的值复制到this->m_lUSN,或者添加公共getter/setter方法以使_tmain()可以读取/设置m_lUSN的值,您将开始看到GetSesstion(1|2)()返回的对象中出现AV。