Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Null vs ZeroMemory

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?

like image 426
Mark Russ Avatar asked Apr 25 '13 09:04

Mark Russ


2 Answers

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

like image 172
Nemanja Boric Avatar answered Sep 20 '22 02:09

Nemanja Boric


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

like image 27
Ivan Aksamentov - Drop Avatar answered Sep 20 '22 02:09

Ivan Aksamentov - Drop