如何用C ++中的新运算符初始化内存?

我刚刚开始进入C ++,我想挑选一些良好的习惯。 如果我刚刚为new运算符分配了一个inttypes的数组,我怎样才能将它们全部初始化为0,而无需循环遍历它们呢? 我应该只使用memset ? 有没有一个“C ++”的方式来做到这一点?

这是一个令人惊讶的鲜为人知的C ++特性(就像没有人给出这个答案一样),但是它实际上有一个特殊的语法来默认初始化一个数组(在技术上,它被称为“value-初始化“):

 new int[10](); 

请注意,您必须使用空圆括号 – 例如,您不能使用(0)或任何其他expression式(这就是为什么这只对默认初始化有用)。

ISO C ++ 03 5.3.4 [expr.new] / 15明确允许这样做:

创buildtypes为T的对象的新expression式按如下方式初始化该对象:

  • 如果new-initializer的forms是(),则该项目被初始化(8.5);

并且不限制允许的types,而(expression-list)forms被明确地限制在同一节中的其他规则,使得它不允许数组types。

假设你真的想要一个数组而不是一个std :: vector,那么“C ++方式”就是这个

 #include <algorithm> int* array = new int[n]; // Assuming "n" is a pre-existing variable std::fill_n(array, n, 0); 

但是请注意,在实际情况下,这实际上只是一个将每个元素赋值为0的循环(除非使用硬件级支持,否则实际上没有其他办法)。

有很多方法来分配一个固有的types的数组,所有这些方法是正确的,但哪一个select,取决于…

手动初始化循环中的所有元素

 int* p = new int[10]; for (int i = 0; i < 10; i++) { p[i] = 0; } 

使用<cstring> std::memset函数

 int* p = new int[10]; std::memset(p, 0, 10); 

使用<algorithm> std::fill_nalgorithm

 int* p = new int[10]; std::fill_n(p, 10, 0); 

使用std::vector容器

 std::vector<int> v(10); // elements zero'ed 

如果C ++ 0x可用,则使用初始化器列表function

 int a[] = { 1, 2, 3 }; // 3-element static size array vector<int> v = { 1, 2, 3 }; // 3-element array but vector is resizeable in runtime 

如果你正在分配的内存是一个带有构造函数的类,那么operator new将会调用这个构造函数,并且保持你的对象初始化。

但是,如果你正在分配一个POD或者没有一个构造函数来初始化对象的状态,那么你就不能在一个操作中用operator new分配内存和初始化那个内存。 但是,您有几个select:

1)改为使用堆栈variables。 您可以一次分配和默认初始化 ,如下所示:

 int vals[100] = {0}; // first element is a matter of style 

2)使用memset() 。 请注意,如果您分配的对象不是POD ,则将其设置为memsetting是一个好主意。 一个具体的例子是,如果你memset一个具有虚函数的类,你将吹走虚表,并让你的对象处于不可用状态。

3)许多操作系统都有你想做的调用 – 分配在堆上,并初始化数据。 一个Windows示例将是VirtualAlloc()

4)这通常是最好的select。 避免必须自己pipe理内存。 您可以使用STL容器来处理任何与原始内存有关的任何事情,包括一次性分配和初始化:

 std::vector<int> myInts(100, 0); // creates a vector of 100 ints, all set to zero 

就在这里:

 std::vector<int> vec(SIZE, 0); 

使用一个vector而不是一个dynamic分配的数组。 其优点包括不必费心地明确删除数组(在向量超出范围时将被删除),并且即使存在抛出的exception也会自动删除内存。

编辑:为了避免进一步的驱动 – 由于不愿意阅读下面的评论的人的downvotes,我应该更清楚地说,这个答案并不是说vector总是正确的答案。 但肯定是一个比“手动”确保删除数组更“C ++”的方法。

现在使用C ++ 11,还有std :: array模拟一个常量大小的数组(可以增长的vector)。 还有std :: unique_ptrpipe理一个dynamic分配的数组(可以与初始化相结合,以回答这个问题的其他答案)。 所有这些都是比手动处理指向数组的指针更加C ++的方式,恕我直言。

std::fill是一种方法。 需要两个迭代器和一个值来填充该区域。 那,或for循环,将(我想)是更多的C ++的方式。

为了将原始整数types的数组专门设置为0, memset很好,尽pipe它可能引发眉毛。 还要考虑calloc ,尽pipe从C ++使用起来有点不方便。

就我而言,我几乎总是使用循环。

(我不喜欢再次猜测人们的意图,但std::vector确实是相同的,最好使用new[] 。)

你总是可以使用memset:

 int myArray[10]; memset( myArray, 0, 10 * sizeof( int )); 

通常对于dynamic项目列表,您使用std::vector

一般来说,我使用memset或循环来处理原始内存dynamic分配,这取决于我预计将来的代码区域如何变化。