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
,但是那个类应该正确地初始化自己。
不要忘记重写new
和delete
和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_alloc
exception。 或者类似的,我将不得不查看,稍后更新。
哦,你也可能想重写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的数组。