ZeroMemory question

Aug 18, 2014 at 10:16am
 
WNDCLASSEX wc = {0};


1
2
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));


Is there a difference between the first and second code? Does ZeroMemory set all bytes of the structure to zero?
Aug 18, 2014 at 1:07pm
Aug 18, 2014 at 1:33pm
and its worth mentioning that these both use memset implicitly when compiled in vs compiler.
Aug 18, 2014 at 2:50pm
@tath: That's... misleading.

memset is a dumb block-memory write. struct initialization may not necessarily zero all members -- it will default construct members that have a constructor.

IE: if WNDCLASSEX contained a string, then the former would work, whereas the latter would completely destroy the string object and possibly cause the program to crash.


memset and ZeroMemory have no place in C++ as far as I'm concerned. You should prefer the first form.
Aug 18, 2014 at 3:09pm
PLease give an example to see when this code will crash. Use your own structure instead of WNDCLASSEX:
1
2
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));


You are not allowed to add anything between these 2 lines :)
Aug 18, 2014 at 3:57pm
Okay:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <vector>
#include <string>

struct MyStruct
{
    std::vector<int>  foo;
    std::string bar;
};

int main()
{
    {
        MyStruct m;
        ZeroMemory(&m, sizeof(m));
    } // <- potential crash here
}



EDIT:

or... if that's not good enough:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <vector>
#include <string>
#include <Windows.h>

class FooBar
{
public:
    FooBar() : val(1) {}
    ~FooBar() { int p = 5 / val; }

private:
    int val;
};

struct MyStruct
{
    FooBar      fb;
};

int main()
{
    {
        MyStruct m;
        ZeroMemory(&m, sizeof(m));
    } // <- crash here
}



The point is... memset (and ZeroMemory) destroy encapsulation by doing a dumb memory write. That is bad bad bad bad.

EDIT2:

Just in case that was not satisfactory for someone *cough*...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <string>
#include <Windows.h>

using namespace std;

class FooBar
{
public:
    FooBar(int page = 0, int size = 10)
        : buffer(new string[size])
        , cur( buffer + page )
        {}
        
    FooBar::~FooBar()
    {
        delete[] buffer;
    }
    
    string& operator () ()
    {
        return *cur;
    }

private:
    string* buffer;
    string* cur;
};

struct MyStruct
{
    FooBar      fb;
};

int main()
{
    {
        MyStruct m;
        ZeroMemory(&m, sizeof(m));  // <- memory leak
        
        cin >> m.fb();  // <- crash
    }
}
Last edited on Aug 18, 2014 at 8:38pm
Aug 18, 2014 at 8:51pm
@ OP: The point is that you should be wrapping these structs, especially the common as dirt ones that are initialization heavy like WNDCLASSEX, so that they get built by a proper C++ constructor instead of just aping the code you see on MSDN. Once you've done this there won't be a need to blank out the contents of the struct only to immediately write into it with virtually the same information every single time you go to use an instance of one. If nothing else you'll save yourself a lot of typing in future projects.
Topic archived. No new replies allowed.