C + +:新的调用行为像calloc?

有没有一个电话,我可以让new来有零,如calloc内存?

相反,有些人在回答中说,这可能的。

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

将零初始化所有字符(实际上,它被称为值初始化,但是对于标量types的数组的所有成员,值初始化将是零初始化)。 如果那是你以后的事情

值得注意的是,它也适用于没有用户声明的构造函数的(types的)types的数组,在这种情况下,它们的任何成员都是值初始化的:

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

这不是什么扩展或什么东西。 它在C ++ 98中的工作和performance也一样。 就在那里,它被称为默认初始化,而不是值初始化。 但是,零初始化在标量或PODtypes的标量或数组的情况下都可以完成。

不,但创build一个类似于calloc的新版本相当容易。 这可以用与新的无投掷版本相同的方式来完成。

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; } 

现在,您可以执行以下操作来获取零内存的新内容

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

另外,你还需要做一些其他有趣的事情,比如define new [],这也是相当简单的。

不,甚至不要想像做这样的事情:

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

你最终可能会毁掉你的VTABLE(如果你的class级有)。

我会build议使用构造函数来清除你的类的内部内存(variables)。

不。 它总是默认初始化分配的项目,这在基元的情况下什么都不做。 你必须用std :: uninitialized_fill_n调用或类似的方式来跟踪它。

你可以做一个new的operator new重载,并从calloc()获取原始内存。 这样在构造函数运行之前内存就被擦掉了,所以这里没有问题。

任何覆盖新的类自己不会得到你的特殊的基于calloc()new ,但是那个类应该正确地初始化自己。

不要忘记重写newdelete和arrays版本…

就像是:

 #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); } 

请注意,这些简单的版本并不完全是他们应该的 – new操作符应该运行在调用new_handler (如果已安装)的循环中,并且只在没有new_handler抛出bad_allocexception。 或者类似的,我将不得不查看,稍后更新。

哦,你也可能想重写no_throw版本。

我使用macros:

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

使用它:

 Whatever* myWhatever = newclear(Whatever); 

(这里使用“放置新的”像其他解决scheme一样)

不可以。您必须手动将内存清零。 请记住, new不仅仅是分配内存,还有通过构造函数进行初始化。 这是calloc在C中的方便之处(它没有初始化函数)。 你可以自由地写一个new的封装,甚至使用calloc ,但大多数时间非POD对象这没有多大意义。

如果你不坚持使用new ,你可以简单地使用vector: vector<char> buffer; buffer.resize(newsize); vector<char> buffer; buffer.resize(newsize); 内容将被清零。

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

如果你愿意的话,你可以覆盖全局的new运算符。

你可以说:

 vector <char> v( 100, 0 ); 

它使用new创build一个连续的100个字符的数组,并将它们初始化为零。 然后可以使用vector的[]运算符访问数组,或者通过执行以下操作:

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

请注意,这也使您不必调用delete来释放分配的内存。

是。

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

对于数组,你可以使用类似memset的东西。 对于Windows使用ZeroMemory或SecureZeroMemory。

编辑:请参阅@ litb的post,他展示了如何使用上面的非直接初始化来初始化为0的数组。