Null 与 ZeroMemory

Posted

技术标签:

【中文标题】Null 与 ZeroMemory【英文标题】:Null vs ZeroMemory 【发布时间】:2013-04-25 09:02:21 【问题描述】:

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

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

我发现使用 DirectX API,无论您是否对对象进行零内存,应用程序仍然可以工作,但有些示例使用了零内存,有些则没有。

谁能澄清这些事情?

【问题讨论】:

这篇文章很有帮助:blogs.msdn.com/b/oldnewthing/archive/2005/06/28/433341.aspx Which one to use - memset() or value initialization to zero out a struct?的可能重复 【参考方案1】:

ZeroMemory 用零填充一块内存。

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

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

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

【讨论】:

啊!这很有意义!现在我知道为什么一个人应该ZeroMemory 的一个很好的理由。 完全印证了我的想法完美描述 请注意,如果您出于安全原因(例如密码/密钥)进行归零,您希望使用 SecureZeroMemory(),因为在某些情况下可以优化掉常规的 ZeroMemory。【参考方案2】:

这是完全不同的事情。 ZeroMemory macro 用零填充一块内存。将指针设置为 NULL……好吧,它使它指向无处。

示例。假设您有指针 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)

如果你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-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)

将其应用到 DirectX

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

【讨论】:

哇!非常详细的答案!当对象是 POD 时,一个人是否应该在设置为 NULL 之前始终 ZeroMemory @Mark 你为什么痴迷于归零?调用ZeroMemory(或memset(..., 0, ...),如果你想将内存归零。如果你不这样做,不要这样做。 @Mark Russ 不,你不应该总是这样做。但是,如果您需要这样做,那就去做吧=)【参考方案3】:

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

这不同于将对象的内容设置为“所有位为零”,这是ZeroMemory() 所做的。您通常只能对 structs 执行此操作,而不是可能反应非常糟糕的成熟 C++ 对象。

【讨论】:

【参考方案4】:

ZeroMemory() 将内存设置为 0。也就是说,它将清除内存。同样将对象(指向对象的指针)设置为 NULL 意味着该对象的基地址被初始化为 0。

【讨论】:

【参考方案5】:

ZeroMemory 用于将较大的内存块设置为零。它不应该用于不是“POD”(普通旧数据)的对象,即如果您的对象具有构造函数或虚拟方法。

NULL 用于指示指针指向“无”。

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

【讨论】:

【参考方案6】:

Zero memory 将部分内存设置为零,对于更常见的将大向量设置为零的对象是有害的,它工作得很快,大约Null 当您希望指针指向任何内容并且它们的用法取决于您的程序指针或设置内存值

【讨论】:

【参考方案7】:

就良好做法而言,我建议您同时使用两者。

// 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,如果这是一个好习惯,我知道。

【讨论】:

【参考方案8】:

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))

你可以说ZeroMemorymemseting 到0

例子:

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

ZeroMemory 就像格式化驱动器(不是快速格式化)。

认为NULL/nullptr 就像是在擦除一个装满宝藏的坚固金库的大门,因此您将永远无法进入它。鉴于,ZeroMemory 正在摧毁强大的保险库的内容,使所有宝藏和里面的其他一切都无效;你可以访问它,但那里什么都没有。这就是我对他们的看法。

【讨论】:

以上是关于Null 与 ZeroMemory的主要内容,如果未能解决你的问题,请参考以下文章

mysql中is null 与 = null

Jasmine:Matcher 与 undefined 和 null 不同(!= undefined 和!= null)

在合并语句中将 Null 与 Null 进行比较

253 undefined与null的区别,null的使用,严格区别变量类型与数据类型

如果一列为 Null,则 SQL 返回 Null(与 COALESCE() 相反)

null与undefined的区别