我是否可以致电new
将calloc
内存归零?
答案 0 :(得分:73)
与某些人在答案中所说的相反, 是可能的。
char * c = new char[N]();
零会初始化所有字符(实际上,它称为值初始化。但是值初始化将为标量类型数组的所有成员进行零初始化)。如果这就是你所追求的。
值得注意的是,它也适用于没有用户声明的构造函数的(类数组)类型,在这种情况下,它们的任何成员都是值初始化的:
struct T { int a; };
T *t = new T[1]();
assert(t[0].a == 0);
delete[] t;
这不是某种延伸或其他什么。它在C ++ 98中的工作和行为也是一样的。就在那里它被称为默认初始化而不是值初始化。但是,对于标量或标量或POD类型的数组,在两种情况下均进行零初始化。
答案 1 :(得分:11)
不,但创建一个像calloc一样的新版本相当容易。它的实现方式与实现no-throw版本的新方法完全相同。
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();
此外,您还需要做其他有趣的事情,例如定义new [],这也很简单。
答案 2 :(得分:5)
没有。甚至不要想做类似的事情:
YourClass *var = new YourClass;
memset(var, 0, sizeof(YourClass));
你最终可能会破坏你的VTABLE(如果你的班级有一个)。
我建议使用构造函数来清除类的内部存储器(变量)。
答案 3 :(得分:2)
不。它总是默认初始化分配的项目,在基元的情况下什么都不做。您必须使用std :: uninitialized_fill_n调用或类似方法进行跟进。
答案 4 :(得分:2)
您可以对运算符new
执行全局重载,并从calloc()
获取原始内存。这样在构造函数运行之前内存就会被擦除,所以那里没有问题。
任何自己覆盖新内容的类都不会获得基于calloc()
的特殊new
,但是该类应该正确初始化自己。
不要忘记覆盖new
和delete
以及数组版本......
类似的东西:
#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
的循环中运行(如果安装了一个)并且只抛出{{1如果没有bad_alloc
,则会出现异常。或类似的东西,我将不得不查找并稍后更新。
哦,您可能还希望覆盖new_handler
版本。
答案 5 :(得分:1)
我使用宏:
#define newclear(TYPE) new(calloc(sizeof(TYPE), 1)) TYPE();
使用它:
Whatever* myWhatever = newclear(Whatever);
(这与其他解决方案一样使用“placement new”)
答案 6 :(得分:0)
不。你必须手动将内存归零。请记住,new
不仅仅是分配内存,还包括通过构造函数初始化。这是calloc
在C中很方便的地方(没有初始化函数)。您可以自由地在new
上写一个包装器,甚至可以使用calloc
,但是对于非POD对象,大多数情况下这都没有多大意义。
答案 7 :(得分:0)
如果您不坚持使用new
,则只需使用vector:vector<char> buffer; buffer.resize(newsize);
即可将内容归零。
答案 8 :(得分:0)
是。
int* p_scalar = new int(5);//Does not create 5 elements, but initializes to 5
对于数组,您可以使用类似memset的内容。对于Windows,使用ZeroMemory或SecureZeroMemory。
编辑:请参阅@ litb的帖子,他展示了如何使用非直接初始化(如上所述)为数组初始化为0。
答案 9 :(得分:0)
class MyClass {
public:
void* operator new(size_t bytes) {
return calloc(bytes, 1);
}
}
如果您愿意,可以覆盖全局新操作符。
答案 10 :(得分:0)
你可以说:
vector <char> v( 100, 0 );
使用new创建一个包含100个字符的连续数组,并将它们全部初始化为零。然后,您可以使用vector的[]运算符或执行以下操作来访问数组:
char * p = &v[0];
p[3] = 42;
请注意,这也使您无需调用delete来释放已分配的内存。