Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

memset for initialization in C++

Tags:

c++

memset is sometimes used to initialize data in a constructor like the example below. Does it work in general ? Is it a good idea in general?

class A {
public:
   A();
private:
   int a;
   float f;
   char str[35];
   long *lp;
};

A::A()
{
   memset(this, 0, sizeof(*this));
}
like image 465
skydoor Avatar asked Mar 20 '10 02:03

skydoor


People also ask

What is memset used for in c?

The memset() function sets the first count bytes of dest to the value c. The value of c is converted to an unsigned character.

Is memset available in c?

memset() in C with examples. memset() is used to fill a block of memory with a particular value.

Why does memset only work for 0 and 1?

memset allows you to fill individual bytes as memory and you are trying to set integer values (maybe 4 or more bytes.) Your approach will only work on the number 0 and -1 as these are both represented in binary as 00000000 or 11111111 .

What is memcpy and memset in c?

memcpy() copies from one place to another. memset() just sets all pieces of memory to the same. For example here sets string length of the string str to * (or whatever second argument of the memset).


2 Answers

Don't use memset. It's a holdover from C and won't work on non-PODs. Specifically, using it on a derived class that contains any virtual functions -- or any class containing a non-builtin -- will result in disaster.

C++ provides a specific syntax for initialization:

class A {
public:
   A();
private:
   int a;
   float f;
   char str[35];
   long *lp;
};

A::A()
    : a(0), f(0), str(), lp(NULL)
{
}

To be honest, I'm not sure, but memset might also be a bad idea on floating-points since their format is unspecified.

like image 195
rlbond Avatar answered Sep 29 '22 10:09

rlbond


It's a terrible idea. You're just tromping over data, paying no heed to how objects should be initialized. If your class is virtual, you're likely to wipe out the vtable pointer as well.

memset works on raw data, but C++ isn't about raw data. C++ creates abstractions, so if you want to be safe you use those abstractions. Use the initializer list to initialize members.

You can do it to POD types:

struct nothing_fancy_here
{
    bool b;
    int i;
    void* p;
};

nothing_fancy_here x;
memset(&x, 0, sizeof(x));

But if you're doing it on this, that means you're in a user-defined constructor and no longer qualify as a POD type. (Though if all your members are POD it might work, as long as none contain 0 as a trap value. I'm sure not sure if any other sources of undefined behavior come into play here.)

like image 42
GManNickG Avatar answered Sep 29 '22 12:09

GManNickG