dre*_*lax 163 c++ memory-management initialization new-operator
我刚刚开始进入C++,我想养成一些好习惯.如果我刚刚int使用new运算符分配了一个类型的数组,我怎么能将它们全部初始化为0而不用自己循环遍历它们?我应该用memset吗?有没有"C++"方法呢?
Pav*_*aev 368
这是一个令人惊讶的鲜为人知的C++特性(事实证明,没有人将此作为答案),但它实际上有默认初始化数组的特殊语法(从技术上讲,它被称为"值 - 初始化"在标准中":
new int[10]();
Run Code Online (Sandbox Code Playgroud)
请注意,您必须使用空括号 - 例如,您不能使用(0)或任何其他表达式(这就是为什么这仅对默认初始化有用).
这是ISO C++ 03 5.3.4 [expr.new]/15明确允许的,它表示:
创建类型为T的对象的new-expression初始化该对象,如下所示:
...
- 如果new-initializer的格式为(),则该项是值初始化的(8.5);
并且不限制允许此类型的类型,而T表单由同一部分中的其他规则明确限制,以使其不允许数组类型.
Tyl*_*nry 25
假设你真的想要一个数组而不是std :: vector,那么"C++方式"就是这个
#include <algorithm>
int* array = new int[n]; // Assuming "n" is a pre-existing variable
std::fill_n(array, n, 0);
Run Code Online (Sandbox Code Playgroud)
但请注意,在引擎盖下,这实际上只是一个循环,将每个元素分配给0(实际上没有其他方法可以做到这一点,除非有一个具有硬件级支持的特殊架构).
mlo*_*kot 23
有许多方法可以分配一个内在类型的数组,所有这些方法都是正确的,尽管选择哪一种,取决于......
手动初始化循环中的所有元素
int* p = new int[10];
for (int i = 0; i < 10; i++)
{
p[i] = 0;
}
Run Code Online (Sandbox Code Playgroud)
使用std::memset来自的功能<cstring>
int* p = new int[10];
std::memset(p, 0, 10);
Run Code Online (Sandbox Code Playgroud)
使用std::fill_n算法<algorithm>
int* p = new int[10];
std::fill_n(p, 10, 0);
Run Code Online (Sandbox Code Playgroud)
使用std::vector容器
std::vector<int> v(10); // elements zero'ed
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Sri*_*tha 22
初始化普通动态数组的可能方法。根据您的要求选择一个。
int* x = new int[5]; // gv gv gv gv gv (gv - garbage value)
int* x = new int[5](); // 0 0 0 0 0
int* x = new int[5]{}; // 0 0 0 0 0 (Modern C++)
int* x = new int[5]{1,2,3}; // 1 2 3 0 0 (Modern C++)
Run Code Online (Sandbox Code Playgroud)
如果要分配的内存是一个带有构造函数的类,它可以执行某些有用的操作,则new new将调用该构造函数并保持对象初始化.
但是,如果您正在分配POD或没有初始化对象状态的构造函数的东西,那么您无法在一次操作中分配内存并使用operator new初始化该内存.但是,您有几种选择:
1)改为使用堆栈变量.您可以在一个步骤中分配和默认初始化,如下所示:
int vals[100] = {0}; // first element is a matter of style
Run Code Online (Sandbox Code Playgroud)
2)使用memset().请注意,如果您要分配的对象不是POD,则设置它是个坏主意.一个具体的例子是如果你设置一个具有虚函数的类,你将吹掉vtable并使你的对象处于不可用状态.
3)许多操作系统都有调用你想做的事情 - 在堆上分配并将数据初始化为某些东西.Windows的例子就是VirtualAlloc()
4)这通常是最好的选择.避免必须自己管理内存.您可以使用STL容器来执行您对原始内存所做的任何事情,包括一次性分配和初始化:
std::vector<int> myInts(100, 0); // creates a vector of 100 ints, all set to zero
Run Code Online (Sandbox Code Playgroud)
就在这里:
std::vector<int> vec(SIZE, 0);
Run Code Online (Sandbox Code Playgroud)
使用向量而不是动态分配的数组.好处包括不必费心删除数组(当向量超出范围时删除它)以及即使抛出异常也会自动删除内存.
编辑:为了避免那些懒得阅读下面评论的人进一步推销,我应该更清楚地说明这个答案并没有说向量总是正确的答案.但它肯定是一种比"手动"确保删除数组更多的C++方式.
现在使用C++ 11,还有std :: array模拟一个恒定大小的数组(vs能够增长的向量).还有std :: unique_ptr管理一个动态分配的数组(可以与初始化结合,如在这个问题的其他答案中回答的那样).其中任何一种都比手动处理指向数组的指针更加C++方式,恕我直言.
| 归档时间: |
|
| 查看次数: |
119132 次 |
| 最近记录: |