如何用C ++中的新运算符初始化内存?
我刚刚开始进入C ++,我想挑选一些良好的习惯。 如果我刚刚为new
运算符分配了一个int
types的数组,我怎样才能将它们全部初始化为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_n
algorithm
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分配,这取决于我预计将来的代码区域如何变化。