将对象设置为NULL和使用ZeroMemory之间究竟有什么区别?
我听说在WinAPI(主要是C)中,一个人应该在C对象上使用ZeroMemory是一种很好的做法。我来自C#的背景,这似乎是一个C ++人真正应该知道的东西。
我发现使用DirectX API,无论你是否ZeroMemory对象,应用程序仍然有效,但有些样本使用ZeroMemory而有些样本没有。
任何人都可以澄清这些事情吗?
答案 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
会做同样的事情,并且出于相同的原因建议使用它。这是适当且惯用的。
然而,ZeroMemory
将struct
或class
的内容设置为每字节0字节。
ZeroMemory
(或RtlZeroMemory
)是memset
的预处理器定义,第二个参数设置为0
。
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
正在摧毁强大的保险库中的物品,使所有财宝和其中的所有其他物品无效;您可以访问它,但是那里什么也没有。我就是这么想的。