考虑以下示例:
// someLibrary.h which is exported.
struct HandlePrivate;
typedef HandlePrivate& Handle;
Handle getHandle(int code);
void closeHandle(Handle handle);
// someLibrary.cpp
#include "someLibrary.h"
struct HandlePrivate{};//definition of HandlePrivate;
Handle getHandle(int code)
{
static HandlePrivate instance;
return code >= 0
? instance
: ( *(HandlePrivate*)0); // Hack, I know it's UB.
}
现在,其他程序员使用这个库:
// userSource.cpp
#include "someLibrary.h"
void foo(int code)
{
Handle h = getHandle(code);
// some user code
closeHandle(h);
}
问题:什么时候可能会破坏用户代码(崩溃或坏事),如果“SomeLibrary”作者使用该hack(UB)?
如果用户仅使用Windows和Visual Studio 2010,则答案会更改吗?
因为,以下示例没有崩溃! :
#include <functional>
#include <type_traits>
#include "someLibrary.h"
void foo(int code)
{
typedef std::reference_wrapper< std::remove_reference<Handle>::type> reference;
reference h = getHandle(code);
closeHandle(h); // is not crash, if code = -1 !!!!!!!!!!
//但是,std :: reference_wrapper :: operator&amp;() - 使用取消引用指针0。 }
答案 0 :(得分:0)
当指针设置为零时,它指向地址为零的东西。地址可以是物理地址0或逻辑(相对于您的用户空间)地址。
解除引用零指针的唯一时间是当地址为零的存储器时,应用程序可以访问地址零(某些操作系统不允许访问各种地址)。
例如,在某些嵌入式系统中,地址零是一个包含起始程序地址的向量。要读取地址向量的值,必须分配一个值为零的指针并取消引用它。
使用空指针访问对象方法是未定义的行为。如果方法不使用任何数据成员,您可能会很幸运。如果该方法使用数据成员,则该方法希望这些数据成员位于地址0附近。
如果要在不创建对象实例的情况下访问对象方法,请将方法声明为static
。