Null vs ZeroMemory

Mar*_*uss 5 c c++ directx null winapi

将对象设置为NULL和使用ZeroMemory之间究竟有什么区别?

我听说在WinAPI(主要是C)中,一个人应该在C对象上使用ZeroMemory是一种很好的做法.我来自C#的背景,这似乎是一个C++人真正应该知道的东西.

我发现使用DirectX API,无论你是否ZeroMemory对象,应用程序仍然有效,但有些示例使用ZeroMemory,有些则没有.

任何人都可以澄清这些事情吗?

Nem*_*ric 5

ZeroMemory 用零填充内存块。

将指针设置为 NULL 只会使指针指向空,这与用零填充指针指向的内存不同(例如,您仍然可以通过该指针访问该内存)。

在您对该对象做任何有用的事情之前,您可能需要用更有意义的东西替换这些零 - 这就是为什么两个程序都使用ZeroMemory或不工作的原因。

ZeroMemory在此上下文中的原因是您可以轻松找到在访问点未初始化的对象上的操作(例如,Visual Studio 正在使用0x0c0c0c0c/* 或类似 */填充未初始化的内存,因此当您在调试期间遇到此模式时,您知道该对象尚未初始化)。

  • 请注意,如果您出于安全原因(例如密码/密钥)归零,则您希望使用 SecureZeroMemory() 作为常规 ZeroMemory 在某些情况下可以优化掉。 (2认同)

Iva*_*rop 5

这是完全不同的事情。ZeroMemory 宏用零填充内存块。将指针设置为 NULL...这使它指向任何地方。

例子。假设您有指向“Type”类型p对象的指针:o

struct Type
{
    int i;
    float f;
    bool b;
};
Type o;
Type* p = &o;

// In memory that will be something like this:
// "o" internals = [010101010001010010110010010010100011001001010000011...]
// "p" address = 0x00830748
//(number of bits and hex adress is just example)
Run Code Online (Sandbox Code Playgroud)

如果你ZeroMemory是:

ZeroMemory(&o, sizeof(o));
// ---- or -----
ZeroMemory(p, sizeof(o));

// In memory we will have:
// "o" internals = [000000000000000000000000000000000000000000000000000...]
// "p" address = 0x00830748
Run Code Online (Sandbox Code Playgroud)

现在里面的所有变量的o值都为零:

cout << o.i; // 0
cout << o.f; // 0.0f
cout << o.b; // false

cout << p->i; // 0
cout << p->f; // 0.0f
cout << p->b; // false
Run Code Online (Sandbox Code Playgroud)

如果你NUll-ify 指针:

p = NULL;
// In memory we now have:
// "o" internals = [010101010001010010110010010010100011001001010000011...]
// "p" address = 0x00000000
Run Code Online (Sandbox Code Playgroud)

如果现在取消引用,p您将得到未定义的行为:

int a = p->i; // Access voilation reading location 0x00000000
Run Code Online (Sandbox Code Playgroud)

如果你NUll-ify对象:Type如果没有重载的operator=() ,它将无法编译

o = NULL; // error C2679: binary '=' : no operator found 
          // which takes a right-hand operand of type 'int' 
          // (or there is no acceptable conversion)
Run Code Online (Sandbox Code Playgroud)

将其应用到 DirectX

当您使用 DirectX 时,您必须填写一些结构体以将它们传递给 API 函数。这就是神奇的地方。您可以将ZeroMemory其设置为 0 值,这主要是默认值,然后只需填写所需的值,简化您的代码并防止您因奇怪的值而出错(如果您创建对象并且不会设置某些成员变量,它将包含垃圾值)。