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?

9
  • 1
    sizeof( TYPE ) * 327 not object itself Commented Mar 14, 2013 at 10:56
  • Provide the correct default constructor. Commented Mar 14, 2013 at 10:57
  • @DenisErmolin Thanks for catching that. Commented Mar 14, 2013 at 10:57
  • I'm pretty sure that many of your objects don't have trivial copy/default constructor. A memset is not the way. Commented Mar 14, 2013 at 10:57
  • 2
    @Jon NO! std::string will panic if you 0 it out! Commented Mar 14, 2013 at 10:57

4 Answers 4

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;
};
Sign up to request clarification or add additional context in comments.

4 Comments

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 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 stackoverflow.com/q/2099692/1741542 for a discussion about uninitialized member variables.
@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 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.
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.

Comments

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.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.