Null vs ZeroMemory
Asked Answered
M

8

6

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?

Maurist answered 25/4, 2013 at 9:2 Comment(2)
This article is helpful: blogs.msdn.com/b/oldnewthing/archive/2005/06/28/433341.aspxMerwin
possible duplicate of Which one to use - memset() or value initialization to zero out a struct?Carilyn
C
5

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

Cimmerian answered 25/4, 2013 at 9:11 Comment(3)
Ahh! That makes A LOT of sense! Now I know a good reason for why a person should ZeroMemory.Maurist
exactly confirms my idea perfect descriptionBalladmonger
Note that if you're zeroing for security reasons, like password/keys, you want to use SecureZeroMemory() as a regular ZeroMemory can be optimized away in some cases.Dismay
C
5

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

Curtin answered 25/4, 2013 at 9:37 Comment(3)
Wow! Great detailed answer! Should a person always ZeroMemory before setting to NULL when the object is POD?Maurist
@Mark Why are you obsessed with zeroing things? Call ZeroMemory (or memset(..., 0, ...) if you want to zero memory. Don't if you don't.Merwin
@Mark Russ No, you shouldn't do it always. But do it if you need to do it =)Curtin
O
3

In C and C++, "an object" cannot be set to NULL. Pointers to objects can be set to NULL, which means that the pointer itself points as nothing ("the null object").

This is distinct from setting the contents of an object to "all bits zero", which is what ZeroMemory() does. You can typically only do this for structs, not full-fledged C++ objects which might react very badly.

Othaothe answered 25/4, 2013 at 9:6 Comment(0)
S
2

ZeroMemory() sets the memory with the value 0. That is it will clear the memory. Also setting an object(pointer to the object) to NULL means the base address of that object is initialized to 0.

Scarabaeus answered 25/4, 2013 at 9:5 Comment(0)
T
0

ZeroMemory is for setting larger chunks of memory to zero. It should not be used on objects that aren't "POD" (plain old data), that is if your object has a constructor or virtual methods.

NULL is used to indicate a pointer is pointing at "nothing".

Technically, you will get the same result from ZeroMemory(pointer, sizeof(pointer)); as pointer = NULL;, but a) the second is clearer, and b) it is most likely as fast or faster to do the latter.

Talamantes answered 25/4, 2013 at 9:6 Comment(0)
B
0

Zero memory sets part of memory to zero and it's harmful to use for objects more common for setting a large vector to zero and it works fast and about Null it's more common when you want a pointer points to nothing and their usage depends on your program pointers or setting a memory value

Balladmonger answered 25/4, 2013 at 9:18 Comment(0)
U
0

In terms of good practice, id recommend you to use both.

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

You may when using DirectX API allocate memory with malloc, in that case a call to ZeroMemory(); will not work as intended. For memory allocated by malloc(); you should probably do a call to free(); instead. When dealing with pointers I mostly set them to NULL right after releasing them, idk if thats a good practice or not.

Unequivocal answered 29/4, 2013 at 18:21 Comment(0)
B
0

NULL sets an arithmetic type variable or a (data or function) pointer variable equal to 0. Since C++11, for pointers only, nullptr does the same thing and is recommended to be used for the same reason; it's proper and idiomatic.

However ZeroMemory set the contents of a struct or class equal to 0 byte-per-byte.

ZeroMemory (or RtlZeroMemory) is a preprocessor define of memset with the second argument set to 0.

void* memset(void* dest, int ch, std::size_t count);

#define ZeroMemory(dest,count) memset((dest),0,(count))

You could say ZeroMemory is memseting to 0.

Example:

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

ZeroMemory is like formatting a drive (not Quick Format).

Think NULL/nullptr as erasing the door of a strong vault full of treasure, as such you will never be able to gain access to it. Whereas, ZeroMemory is destroying the contents of the strong vault nullifying all treasure and everything else inside; you can gain access to it, but there's nothing in there. That's how I think about them.

Bogeyman answered 17/9, 2020 at 8:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.