4

在 C++11 中,当我使用它分配动态数组时,T *array = new T[n];已经归零(使用 gcc 4.7.2,Ubuntu 12.10 64 位)。

  1. 这是 C++11 规范强制要求的吗?
  2. 如何在不将其项归零的情况下分配一个数组?这应该会快一点。

编辑:我已经检查了T = int.

gcc cxx 标志-std=gnu++11 -O3 -ffast-math -fno-rtti

4

4 回答 4

6

§ 5.3.4

如果省略 new-initializer,则默认初始化对象 (8.5);如果不执行初始化,则对象具有不确定的值。

new-initializer 是()in new T[] (),您已将其省略。

§ 8.5 / 6

默认初始化 T 类型的对象意味着:

— 如果 T 是(可能是 cv 限定的)类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是非良构的);

— 如果 T 是数组类型,则每个元素都是默认初始化的;

— 否则,不执行初始化。

int[] 是默认初始化的 -> 每个元素都是默认初始化的。

“这是由 C++11 规范强制执行的吗?”:“不执行初始化”,所以不,如果 T 没有归零构造函数(即 T 是 POD),则不强制归零。对于 T=int,不必执行归零。

为什么它仍然是零?如果您的程序从操作系统分配新内存,操作系统会为您清零新内存。如果您可以读取另一个可能存储敏感数据的程序的内存,那将是非常危险的。但是,如果您写入该内存,释放它并再次分配一些内存,则不应将其归零。

于 2012-11-27T21:36:05.010 回答
4

它不会被初始化(当然,如果 T 是一个类,仍然会调用构造函数)。要强制值初始化(这对新手来说可能会产生误导 - 我们称之为零初始化,它适用于原始类型,如int),请执行

new T[N]()

也就是说,只需放一对括号。

于 2012-11-27T21:45:52.517 回答
3

取决于你的实际类型T。在某些条件下,它可能会被初始化为零。请参见此处:C++ 中的默认初始化

于 2012-11-27T21:20:45.800 回答
2

即使您可以使用 C++ 功能来动态分配未初始化的内存 ( std::get_temporary_buffer?),操作系统的 libc 的底层实现malloc()和在您的操作系统的 libc 中也是对大型分配块(其中large是一个可调参数)::new使用匿名。并且匿名总是零初始化。mmap()mmap()

于 2012-11-27T21:39:00.567 回答