1
struct OBJECT
{
unsigned int Var1;
std::string Str1;
...
bool YesNo;
};

OBJECT Obj[ 327 ];

I am confused about how to zero-out Obj. It has several different type of elements. Do I have to set all of its member to 0? Like... Obj[0].Str = ""; ? So the question is, what is the proper way of doing it?

My attempt:

::memset( &Obj, 0, sizeof( Obj ) );

I am not sure if I am doing it correctly...

Oh and are there any faster way to zero-out an array?

CLearner
  • 532
  • 1
  • 6
  • 17

4 Answers4

10

Don't do it this way, because you have non trivial members in your struct (e.g. std::string). You can do this if all your members are only simple data types, like int, char, double or pointers.

The correct way for this type of struct is to define a constructor, which initializes all members properly

struct OBJECT {
    OBJECT() : Var1(0), YesNo(false), ... {}

    unsigned int Var1;
    std::string Str1;
    ...
    bool YesNo;
};
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • There's a drawback with the idea though: upon adding a new member, it is easy to forget to update the constructors, whilst the *memset/std∷fill* way don't need to be updated. – Hi-Angel Apr 26 '16 at 07:04
  • 1
    @Hi-Angel Yes, you're right as long as you have only trivial members. With more complex members though, `memset` might even be dangerous, because it stomps over member's memory. See http://stackoverflow.com/q/2099692/1741542 for a discussion about uninitialized member variables. – Olaf Dietsche Apr 26 '16 at 07:20
  • @OlafDietsche thank you for the advice; I tried, and I've to say there's doesn't seem to be good a method to definitely find unitialized variables. `-Weffc++` option gives hundreds wrong warnings, valgrind is only useful in runtime whilst I'm working with app whose runtime is in embedded device. Perhaps cppcheck can be useful for this — not sure, I didn't try that specific problem. – Hi-Angel Apr 27 '16 at 09:11
  • @Hi-Angel I haven't tried these myself, so cannot really comment. A quick check shows, neither `-Weffc++` nor cppcheck seem very reliable. `-Weffc++` complains even when there's a default constructor for a non POD type, and it doesn't complain at all, when there's no constructor defined. cppcheck doesn't show any warning at all. Maybe newer versions are better. – Olaf Dietsche Apr 27 '16 at 15:47
3

The "correct" way is to add a constructor method for your struct that initialises any member variables that don't have constructors of their own, e.g.:

OBJECT_STRUCT()
: Var1(0)
, YesNo(false)
{
}

In that example you'll note that Str1 was not initialised; this is because std::string has its own constructor that initialises it.

Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
3

Either provide a custom default constructor or use the compiler defined default constructor:

std::fill(std::begin(Obj), std::end(Obj), OBJECT());

Note that the fill approach fill only work if you use the default constructor.

Zeta
  • 103,620
  • 13
  • 194
  • 236
1

You should change your declaration to

struct OBJECT
{
    unsigned int Var1;
    std::string Str1;
    ...
    bool YesNo;

   OBJECT()
   : Var1()
   , Str1()
   , ...
   , YesNo(false)
   {
       // Do Nothing
   }
};

The array - which you should use over std::array or std::vector - will initialise the objects.

Alex Chamberlain
  • 4,147
  • 2
  • 22
  • 49