Null vs ZeroMemory

Null vs ZeroMemory

本文关键字:ZeroMemory vs Null      更新时间:2023-10-16

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

我听说在WinAPI(主要是C(中,一个人应该在C对象上使用ZeroMemory是一种很好的做法。我有C#的背景,这似乎是一个C++程序员应该知道的。

我发现使用DirectX API,无论你是否使用ZeroMemory对象,应用程序仍然可以工作,但有些示例使用ZeroMemory,有些则不使用。

有人能澄清这些事情吗?

ZeroMemory用零填充内存块。

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

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

在这种情况下使用ZeroMemory的原因是,您可以很容易地找到在访问点未初始化的对象上的操作(例如,Visual Studio正在用0x0c0c0c0c/*或类似的*/填充未初始化的内存,因此当您在调试过程中遇到这种模式时,您知道该对象尚未初始化(。

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

示例。假设您有指向类型为"type"的对象o的指针p

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)

如果您ZeroMemory它:

ZeroMemory(&o, sizeof(o));
// ---- or -----
ZeroMemory(p, sizeof(o));
// In memory we will have:
// "o" internals = [000000000000000000000000000000000000000000000000000...]
// "p" address = 0x00830748

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

如果您使用NUll-ify指针:

p = NULL;
// In memory we now have:
// "o" internals = [010101010001010010110010010010100011001001010000011...]
// "p" address = 0x00000000

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

int a = p->i; // Access voilation reading location 0x00000000

如果您NUll验证对象:如果Type没有重载运算符=((,它将不会编译

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

将其应用于DirectX

使用DirectX时,必须填写一些结构,才能将它们传递给API函数。这就是魔术的地方。您可以将它ZeroMemory的值设为0,这通常是默认值,然后只需填写所需的值,即可简化代码,避免出现使用奇怪值的错误(如果您创建对象而不设置某个成员变量,则它将包含垃圾值(。

在C和C++中,"对象"不能设置为NULL指向对象的指针可以设置为NULL,这意味着指针本身不指向任何对象("空对象"(。

这与ZeroMemory()将对象的内容设置为"所有位为零"不同。您通常只能对structs执行此操作,而不能对可能反应非常糟糕的完整C++对象执行此操作。

ZeroMemory((将内存设置为值0。这将清除记忆。另外,将对象(指向对象的指针(设置为NULL意味着该对象的基地址被初始化为0。

ZeroMemory用于将较大的内存块设置为零。它不应该用于非"POD"(纯旧数据(的对象,也就是说,如果您的对象有构造函数或虚拟方法。

NULL用于指示指针指向"无"。

从技术上讲,您将从ZeroMemory(pointer, sizeof(pointer));pointer = NULL;中获得相同的结果,但a(第二个更清晰,b(最有可能以同样快或更快的速度执行后者。

Zero memory将部分内存设置为零,对于更常见的将大向量设置为零的对象使用它是有害的,它工作得很快,而对于Null,当你想让指针指向零时,它更常见,它们的使用取决于你的程序指针或设置内存值,我建议你两者都用。

// Consider mystuff as being a pointer to an object.
ZeroMemory(mystuff); // Makes this part of memory to be clean
mystuff = NULL; // Makes this pointer point to null so you dont access a 0-memory section.

使用DirectX API时,可以使用malloc分配内存,在这种情况下,对ZeroMemory();的调用将无法正常工作。对于由malloc();分配的内存,您可能应该调用free();。在处理指针时,我大多在释放指针后立即将其设置为NULL,我想知道这是否是一种好的做法。

NULL将算术类型变量或(数据或函数(指针变量设置为0。由于C++11,仅针对指针,nullptr也做同样的事情,并且出于同样的原因建议使用;这是地道的。

然而,ZeroMemorystructclass的内容设置为每字节0字节。

ZeroMemory(或RtlZeroMemory(是memset的预处理器定义,第二个参数设置为0

void* memset(void* dest, int ch, std::size_t count);
#define ZeroMemory(dest,count) memset((dest),0,(count))

你可以说ZeroMemorymemset,而不是0

示例:

D3D11_BUFFER_DESC indexBuffDesc;
ZeroMemory(&indexBuffDesc, sizeof(indexBuffDesc));
// or:
memset(&indexBuffDesc,0,sizeof(indexBuffDesc));

ZeroMemory类似于格式化驱动器(而非快速格式化(。

NULL/nullptr看作是抹去了一个装满宝藏的坚固金库的门,这样你就永远无法进入它。而ZeroMemory则是摧毁了坚固金库的内容,使里面的所有宝藏和其他一切都无效;你可以访问它,但里面什么都没有。这就是我对他们的看法。