我想知道在使用new的堆上创建的对象中的内置类型是否会被初始化为零?它是由标准强制还是特定于编译器?
给出以下代码:
#include <iostream>
using namespace std;
struct test
{
int _tab[1024];
};
int main()
{
test *p(new test);
for (int i = 0; i < 1024; i++)
{
cout << p->_tab[i] << endl;
}
delete p;
return 0;
}
运行时,它会打印所有零。
答案 0 :(得分:11)
您可以选择是否需要默认初始化,这会使基本类型(和一般的POD类型)保持未初始化,或值初始化,这会使基本零初始化(和POD)类型。
int * garbage = new int[10]; // No initialisation
int * zero = new int[10](); // Initialised to zero.
这是由标准定义的。
答案 1 :(得分:2)
不,如果你这样做:
int *p = new int;
或
char *p = new char[20]; // array of 20 bytes
或
struct Point { int x; int y; };
Point *p = new Point;
然后p
指向的内存将具有不确定/未初始化的值。
但是,如果您这样做:
std::string *pstring = new std::string();
然后你可以放心,字符串将被初始化为空字符串,但这是因为类构造函数的工作方式,而不是因为对堆分配的任何保证。
答案 2 :(得分:0)
标准没有强制要求。原始类型成员的内存可能包含最后留在内存中的任何值。
我猜有些编译器可能会选择初始化字节。许多人都在调试代码构建中。它们分配一些已知的字节序列,以便在调试时通过程序代码初始化内存时给出提示。
答案 3 :(得分:-1)
使用calloc将返回初始化为0的字节,但这不是标准特定的。 calloc和C以及malloc一样。但是,您将支付使用calloc的运行时开销。
之前给出的关于使用std :: string的建议是非常合理的,因为毕竟,你正在使用std,并获得类构造/破坏行为的好处。换句话说,你需要担心的越少,比如数据的初始化,就越不会出错。