problems with initialization of class variables

This is embarrassing, but I'm having repeated problems with un-initialized variables!

In the old days, whenever I allocated a struct, I would start out by just setting the whole thing to 0 with memset/ZeroMemory:

mystruct *s = (mystruct *) new mystruct ;
ZeroMemory((char *) s, sizeof(mystruct)) ;

This had the advantage that if I later modified the structure, in a header far from this allocation code, all the variables started out in a known state.

Unfortunately, C++ constructors don't seem to have any equivalent method, unless I've missed something??

I tried ZeroMemory((char *) this, sizeof(myclass)) ;
and while that didn't kill anything, it also didn't set at least one of the data fields to 0...

Is there any generic way of zeroing all of the data elements in one swell foop?? Individually setting each field to 0 seems very fragile to me, because it will be all too easy for someone in the future to add a new variable to the class, and forget to add it to the constructor...

This is particularly relevant in my current company, where we are all C programmers; I'm experimenting with C++, and will be trying to convert the others as I find advantages, but this is a bad vulnerability...
For POD types, you can still use memset like in C.
C++11 brought non-static member data initializers, which also solve the problem:

1
2
3
4
5
struct Foo
{
  int a=0;
  int b=0;
};
Member initialization lists...

e.g.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Apple{
   public:
      Apple();
      Apple(int,int,bool,const std::string&);
   private:
      int m_seeds;
      int m_leaves;
      bool m_stem;
      std::string m_name;
};
//List begins after :
Apple::Apple() : m_seeds(0), m_leaves(0), m_stem(false), m_name("default")
{
}

//List begins after :
Apple::Apple(int seeds, int leaves, bool stem, const std::string& name) :
   m_seeds(seeds),
   m_leaves(leaves),
   m_stem(stem),
   m_name(name)
{
}

Last edited on
Regarding init lists: I tried that technique, but it doesn't solve the problem of handling change; the init list is specified in the constructor in class.cpp, but variables are added to the private data in class.h. So it's still far too easy to add a variable and forget to initialize it. It turns out that neither "g++ -Wall" nor PcLint will detect a class variable which is not included in the init list.

regarding memset(), I thought I had a size discrepancy between sizeof(class) and the actual data size, but some poking around made me realize that each variable is simply on int boundaries, so bool (which is 1 byte) is taking up 4 bytes. So it looks like I *can* use memcpy; I'll just do that for now.

I still have some other weird problem in my program since I converted some of it to classes, but apparently it doesn't have anything to do with initialization... I may ask more questions here once I know enough to actually know what question to ask!!

It turns out that neither "g++ -Wall" nor PcLint will detect a class variable which is not included in the init list.

But -Weffc++ will.
I tried that technique, but it doesn't solve the problem of handling change; the init list is specified in the constructor in class.cpp, but variables are added to the private data in class.h. So it's still far too easy to add a variable and forget to initialize it.


I see your point, but it is the responsibility of the developer to handle that. Using memset/memcpy may be viable, but it's not c++. You can always argue that down the road both can suffer from similar problems.

It's just something you will have to get used to. Down the road not using the init lists will surely cause more headache maintaining/debugging for an experience c++ developer than the latter.

OH My!!!!
Thank you, Athar! That (-Weffc++)works perfectly!!

I agree with clanmjc, I would rather do things (initialization or anything else) thematically, and init lists are clearly a more thematic way to initialize member variables than memset(). However, without a mechanism to detect missed variables, it was going to be a real, not theoretical, problem. Fortunately, Athar's suggestion solves the problem for me, and I can go back to using the correct method.
Topic archived. No new replies allowed.