0

In C, in order to assure that all structs are zeroed I wrap malloc with:

void* safe_malloc(size_t size){
    void *result = malloc(size);
    memset(result, 0, size); //NULL check ommitted for brevity
    return result;
}

so that I can avoid doing:

struct Foo {
    int bar;
    int bat;
};

struct Foo *tmp = malloc(sizeof(struct Foo));
tmp->bar = 0; 
tmp->bat = 0; // I want to avoid this laundry list of initializers

I want to do something similar for C++ whereby I want all members of a class to be initialized to zero like what is done automatically in Java. There are two problems that come to mind using a solution like the C solution: 1. you cant clear the vtable ptr and 2. a subclass will clear inherited member values.

class Foo {
public:
    int bar;
    int bat;

    Foo(int bar){
        this->bar = bar;
        this->bat = 0; // I dont want to explicitly have to initialize this here
    }
}

class Baz : public Foo {
public:
    int bam;
    Baz(int bar, int bam) : Foo(bar) {
        this->bam = bam;
    }
}

How can I avoid the laundry list equivalent in C++?

chacham15
  • 13,719
  • 26
  • 104
  • 207
  • You could save yourself some trouble and use calloc() instead of safe_malloc(). You should be using the member initialization syntax instead of any if this, e.g. : bar(0), bat(0). – user207421 Apr 23 '14 at 05:16
  • @EJP noted, but `safe_malloc` actually does more in the explicit case that `malloc` returns `NULL`, it just wasnt relevant to the question. – chacham15 Apr 23 '14 at 05:17
  • Then it could call calloc() and avoid the memset(). – user207421 Apr 23 '14 at 05:19
  • @EJP true, but its not really a big difference then (1 loc difference). furthermore, I bet calloc does just what safe_malloc does here. – chacham15 Apr 23 '14 at 05:20
  • 2
    Shouldn't the constructors be *precisely* the methods responsible for default-initializing the data members of a class type? Why is this a big deal to you? You only have to do it once in the ctor, not each time you create a class object. – Cody Gray - on strike Apr 23 '14 at 05:24
  • @CodyGray yes, but I've been burned by someone else forgetting to initialize a member and would like a way to make sure that all members are always initialized. – chacham15 Apr 23 '14 at 05:26
  • 1
    Why spend extra effort to mask potential bugs? If anything, fill the memory with 0xdeadbeef or a similar pattern. – n. m. could be an AI Apr 23 '14 at 05:28
  • @n.m. I see what you are saying, but my intention is that members should be zero by default in the same manner that is true in Java. If there is an error, my preference is that it not cause the application to crash (yes, there are many differing philosophies here, that is just mine). – chacham15 Apr 23 '14 at 05:34
  • 2
    The thing is, at least in the world of C++, failing to initialize a field before using it is a *serious bug*. It *should* crash the application. But that will only happen once, while you're debugging it. Then you'll catch the problem and fix it. And if you always do this in the constructors, there'll only be one place to fix. The user will never experience such a bug and the app will never crash. Default-initializing all members as a matter of course is just going to *hide* bugs, not aid in sussing them out. – Cody Gray - on strike Apr 23 '14 at 05:36
  • @CodyGray thats a nice idea, but practice has shown me that that is not the case. If the member is not a pointer, there is no reason the program will immediately crash anyways. Even if it is, I have seen Windows dereference it without a segfault/sigbus on more than one occasion. As to why that happens in Windows, I have no idea. Furthermore, in the case of a pointer, if I initialize it to NULL and try to dereference it accidentally, it 'should' still cause a crash. In conclusion, seeing as how missing initializers are no more likely to be caught with than without this I would rather have it. – chacham15 Apr 23 '14 at 06:39
  • You could use something like this: http://stackoverflow.com/a/38103250/3223828 – Stuart Gillibrand Jun 29 '16 at 18:22

1 Answers1

2
  1. Prefer calloc over malloc + memset
  2. To zero the objects, choose your constructors wisely.
  3. You can overload new operator to return zeroed memory. (Overload new for a class or globally as per your requirement) This overloaded new should zero the bytes allocated.
Mohit Jain
  • 30,259
  • 8
  • 73
  • 100