Null vs ZeroMemory

时间:2013-04-25 09:02:21

标签: c++ c winapi null directx

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

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

我发现使用DirectX API,无论你是否ZeroMemory对象,应用程序仍然有效,但有些样本使用ZeroMemory而有些样本没有。

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

8 个答案:

答案 0 :(得分:4)

ZeroMemory用零填充一块内存。

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

在您可以对该对象执行任何有用的操作之前,您可能需要将这些零替换为更有意义的内容 - 这就是为什么使用ZeroMemory或不使用ZeroMemory的程序。

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

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

实施例。假设您有一个指针p到“Type”类型的对象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 object: 如果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函数。这里是神奇的地方。您可以ZeroMemory将其值设置为0(大多数是默认值),然后只填写所需的值,简化代码并使您避免使用奇怪的值(如果您创建对象并且不会设置某些成员变量,它将包含垃圾值)。

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

Zero memory将内存的一部分设置为零,并且对于将大向量设置为零更常见的对象是有害的,并且它可以快速运行并且大约Null当你想要指针点时它更常见什么都没有,他们的用法取决于您的程序指针或设置内存值

答案 6 :(得分:0)

在良好做法方面,id建议您同时使用。

// 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,如果这是一个好的练习,则为idk。

答案 7 :(得分:0)

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

您可以说ZeroMemory正在memset0

示例:

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

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

NULL / nullptr看作是擦除了一个拥有宝藏的强大保管库的门,因此您将永远无法使用它。而ZeroMemory正在摧毁强大的保险库中的物品,使所有财宝和其中的所有其他物品无效;您可以访问它,但是那里什么也没有。我就是这么想的。