What exactly is the difference between setting an object to NULL and using ZeroMemory?
I hear that it is good practice in the WinAPI (which is mostly C) that a person should use ZeroMemory on C objects. I come from a background of C# and this seems like something a C++ guy should really know.
I found that with the DirectX API, whether you ZeroMemory the objects or not, the application still works, but some samples use ZeroMemory and some don't.
Can anyone clarify these things?
ZeroMemory
fills a block of memory with zeros.
Setting pointer to NULL will just make the pointer to points to nothing, and it is is different than filling memory which pointer is pointing to with zeros (you will still be able to access that memory via that pointer, for example).
Before you can do anything useful with that object, it is likely that you will need to replace these zeros with something more meaningful - so that is why both programs that use ZeroMemory
or not works.
Reason for ZeroMemory
in this context is that you could easily find operations on objects which are not initialized at the point of access (for example, Visual Studio is filling uninitialized memory with 0x0c0c0c0c
/* or similar */, so when you encounter this pattern during debugging, you know that object has not been initialized yet).
It's completely different things. ZeroMemory macro fills a block of memory with zeros. Setting pointer to NULL... well it makes it pointing to nowhere.
Examples. Assume you have pointer p
to object o
of type "Type":
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)
If you ZeroMemory
it:
ZeroMemory(&o, sizeof(o));
// ---- or -----
ZeroMemory(p, sizeof(o));
// In memory we will have:
// "o" internals = [000000000000000000000000000000000000000000000000000...]
// "p" address = 0x00830748
All variables inside o
is now has value of zero:
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
If you NUll
-ify pointer:
p = NULL;
// In memory we now have:
// "o" internals = [010101010001010010110010010010100011001001010000011...]
// "p" address = 0x00000000
If now you dereference p
you will get undefined behavior:
int a = p->i; // Access voilation reading location 0x00000000
If you NUll
-ify object:
It will not compile, if Type
don't have overloaded operator=()
o = NULL; // error C2679: binary '=' : no operator found
// which takes a right-hand operand of type 'int'
// (or there is no acceptable conversion)
Applying it to DirectX
When you using DirectX, you must fill-in some structs to pass them to API functions. Here is where the magic. You can ZeroMemory
it to values of 0, which is mostly default ones, and then just fill-in needed values, simplifying your code and keeping you from mistakes with strange values (if you create object and will not set some member variable, it will contain garbage value).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With