Question

Is there a call I can make to new to have it zero out memory like calloc?

Was it helpful?

Solution

Contrary what some are saying in their answers, it is possible.

char * c = new char[N]();

Will zero initialize all the characters (in reality, it's called value-initialization. But value-initialization is going to be zero-initialization for all its members of an array of scalar type). If that's what you are after.

Worth to note that it does also work for (arrays of) class-types without user declared constructor in which case any member of them is value initialized:

struct T { int a; };
T *t = new T[1]();
assert(t[0].a == 0);
delete[] t;

It's not some extension or something. It worked and behaved the same way in C++98 too. Just there it was called default initialization instead of value initialization. Zero initialization, however, is done in both cases for scalars or arrays of scalar or POD types.

OTHER TIPS

No but it's fairly easy to create a new version that acts like calloc. It can be done in much the same way that the no-throw version of new is implemented.

SomeFile.h

struct zeromemory_t{};
extern const zeromemory_t zeromemory;
void* __cdcel operator new(size_t cbSize, const zeromemory_t&);

SomeFile.cpp

const zeromemory_t zeromemory;

void* _cdecl operator new(size_t cbSize, const zeromemory_t&)
{
    void *mem = ::operator new(cbSize);
    memset(mem,0,cbSize);
    return mem;
}

Now you can do the following to get new with zero'd memory

MyType* pMyType = new (zeromemory) MyType();

Additionally you'd need to do other fun things like define new[] which is fairly straight forward as well.

No. Also don't even think of doing something like:

YourClass *var = new YourClass;
memset(var, 0, sizeof(YourClass));

You could end up trashing your VTABLE (if your class has one).

I would recommend using constructors to clear the internal memory (variables) of your class.

Nope. It will always default-initialize the allocated item(s), which in the case of primitives does nothing. You'll have to follow it up with a std::uninitialized_fill_n call or similar.

You could do a global overload of operator new and have it grab the raw memory from calloc(). This way the memory gets wiped before constructors get to run so there's no problems there.

Any class that overrides new on its own will not get your special calloc()-based new, but then that class should be initializing itself correctly anyway.

Don't forget to override both new and delete and the array versions...

Something like:

#include <exception> // for std::bad_alloc
#include <new>
#include <stdlib.h> // for calloc() and free()

void* operator new (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc(); 
 return p;
}


void operator delete (void *p)
{
 free(p); 
}

void* operator new[] (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc();
 return p;
}

void operator delete[] (void *p)
{
 free(p); 
}

Note that these simple versions aren't quite exactly what they should be - the new operator should run in a loop calling the new_handler (if one is installed) and only throwing the bad_alloc exception if there is no new_handler. Or something like that, I'll have to look it up and update later.

Oh, and you might want to also override the no_throw version as well.

i use a macro:

#define newclear(TYPE) new(calloc(sizeof(TYPE), 1)) TYPE();

to use it:

Whatever* myWhatever = newclear(Whatever);

(this uses "placement new" like some other solutions here)

No.You have to manually zero the memory out. Remember, new is not just about allocating memory, but also about initializing via constructors. This is where calloc is handy in C (which does not have initializer functions). You are free to write a wrapper over new or even use calloc, but most of the time for non-POD objects this doesn't make much sense.

if you don't insist using new, you can simply use vector: vector<char> buffer; buffer.resize(newsize); and the content will be zeroed.

class MyClass {
    public:
    void* operator new(size_t bytes) {
        return calloc(bytes, 1);
    }
}

And you can override the global new operator if you like.

You can say:

vector <char> v( 100, 0 );

which creates a contiguous array of 100 characters using new, and initialises them all to zero. You can then access the array with vector's [] operator, or by doing:

char * p = &v[0];
p[3] = 42;

Note this also frees you from having to call delete to free the allocated memory.

Yes.

int* p_scalar = new int(5);//Does not create 5 elements, but initializes to 5

For arrays you can use something like memset. For windows use ZeroMemory or SecureZeroMemory.

Edit: Please see @litb's post, he shows how you can initialize to 0 for arrays using non direct initialization like above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top