将对象设置为NULL和使用ZeroMemory有什么区别呢?
我听说在WinAPI(主要是C语言)中,一个人应该对C对象使用ZeroMemory。我来自C#的背景,这似乎是C ++程序员真正需要知道的。
我发现在DirectX API中,无论你是否使用ZeroMemory,应用程序仍然可以运行,但有些示例使用ZeroMemory,有些则不使用。
能否有人澄清这些问题呢?
将对象设置为NULL和使用ZeroMemory有什么区别呢?
我听说在WinAPI(主要是C语言)中,一个人应该对C对象使用ZeroMemory。我来自C#的背景,这似乎是C ++程序员真正需要知道的。
我发现在DirectX API中,无论你是否使用ZeroMemory,应用程序仍然可以运行,但有些示例使用ZeroMemory,有些则不使用。
能否有人澄清这些问题呢?
这两件事情完全不同。 ZeroMemory宏 可以将一块内存全部填充为0。而将指针设置为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
:
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,然后只需填写所需的值,简化代码并避免出现奇怪值的错误(如果创建对象并且不设置某些成员变量,则其将包含垃圾值)。
NULL
之前总是使用ZeroMemory
? - Mark RussZeroMemory
函数(或者使用 memset(..., 0, ...)
),否则就不需要。 - David HeffernanZeroMemory
函数将一块内存区域清零。
将指针设置为NULL只是使指针指向空,与用0填充指针所指向的内存不同(例如,您仍然可以通过该指针访问该内存)。
在对该对象进行任何有用的操作之前,很可能需要用更有意义的内容替换这些零 - 这就是为什么使用ZeroMemory
或不使用都可以正常工作的原因。
在这种情况下使用ZeroMemory
的原因是,您可能会轻松地找到对未初始化的对象进行操作的情况(例如,Visual Studio正在用 0x0c0c0c0c
/*或类似*/填充未初始化的内存,因此在调试期间遇到此模式时,您就知道对象尚未初始化)。
ZeroMemory
的好理由了。 - Mark RussNULL
。可以将指向对象的指针设置为NULL
,这意味着指针本身指向空(“null对象”)。ZeroMemory()
所做的。您通常只能对structs
执行此操作,而不能对完整的C++对象执行此操作,否则可能会出现非常严重的反应。ZeroMemory()函数将内存设置为0,即清空该内存。将一个对象(指向该对象的指针)设置为NULL意味着该对象的基地址被初始化为0。
从良好的实践角度来看,我建议你两者都使用。
// 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,不知道这是否是一个好习惯。
ZeroMemory
用于将较大的内存块设置为零。它不应该用于那些不是“POD”(普通旧数据)的对象,也就是说,如果您的对象具有构造函数或虚拟方法,则不应使用它。
NULL
用于指示指针指向“无”。
从技术上讲,ZeroMemory(pointer, sizeof(pointer));
和 pointer = NULL;
将得到相同的结果,但是 a) 后者更清晰,b) 执行后者很可能更快。
清零内存
将一部分内存设置为零,对于更常见的用于将大向量设置为零的对象来说是有害的,但它可以快速工作。而空指针
则更常用于当您想要一个指针指向空时,其使用取决于您的程序指针或设置内存值。
NULL
将算术类型变量或(数据或函数)指针变量设置为0。自 C++11 开始,对于指针而言,nullptr
也具有相同的作用,并且出于正确和惯用的原因建议使用它。
然而,ZeroMemory
将 struct
或 class
的内容逐字节设置为0。
ZeroMemory
(或 RtlZeroMemory
)是将第二个参数设置为 0
的 memset
的预处理器定义。
void* memset(void* dest, int ch, std::size_t count);
#define ZeroMemory(dest,count) memset((dest),0,(count))
ZeroMemory
是将memset
设置为0
。D3D11_BUFFER_DESC indexBuffDesc;
ZeroMemory(&indexBuffDesc, sizeof(indexBuffDesc));
// or:
memset(&indexBuffDesc,0,sizeof(indexBuffDesc));
ZeroMemory
就像格式化驱动器(不是快速格式化)。
把 NULL
/nullptr
想象成擦除一个充满宝藏的强力金库门,这样你将永远无法进入。而 ZeroMemory
则是摧毁强力金库内所有宝藏和其他物品的内容;你可以进入其中,但里面什么也没有。这就是我对它们的看法。