如何在 C++ 中使用 new 运算符初始化内存?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2204176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:30:51  来源:igfitidea点击:

How to initialise memory with new operator in C++?

c++initializationmemory-managementnew-operator

提问by dreamlax

I'm just beginning to get into C++ and I want to pick up some good habits. If I have just allocated an array of type intwith the newoperator, how can I initialise them all to 0 without looping through them all myself? Should I just use memset? Is there a “C++” way to do it?

我刚刚开始接触 C++,我想养成一些好习惯。如果我刚刚int使用new运算符分配了一个类型的数组,我如何将它们全部初始化为 0 而不需要自己循环遍历它们?我应该使用memset吗?有没有“C++”的方法来做到这一点?

回答by Pavel Minaev

It's a surprisingly little-known feature of C++ (as evidenced by the fact that no-one has given this as an answer yet), but it actually has special syntax for value-initializing an array:

这是 C++ 的一个令人惊讶的鲜为人知的特性(从没有人给出答案这一事实证明了这一点),但它实际上具有用于值初始化数组的特殊语法:

new int[10]();

Note that you mustuse the empty parentheses — you cannot, for example, use (0)or anything else (which is why this is only useful for value initialization).

请注意,您必须使用空括号——例如,您不能使用(0)或其他任何东西(这就是为什么这只对值初始化有用)。

This is explicitly permitted by ISO C++03 5.3.4[expr.new]/15, which says:

这是 ISO C++03 5.3.4[expr.new]/15 明确允许的,它说:

A new-expression that creates an object of type Tinitializes that object as follows:

...

  • If the new-initializer is of the form (), the item is value-initialized (8.5);

创建类型对象的 new 表达式T初始化该对象如下:

...

  • 如果 new-initializer 的形式为(),则该项目是值初始化的(8.5);

and does not restrict the types for which this is allowed, whereas the (expression-list)form is explicitly restricted by further rules in the same section such that it does not allow array types.

并且不限制允许的类型,而(expression-list)表单在同一部分中受到进一步规则的明确限制,因此它不允许数组类型。

回答by Tyler McHenry

Assuming that you really do want an array and not a std::vector, the "C++ way" would be this

假设您确实想要一个数组而不是 std::vector,那么“C++ 方式”就是这样

#include <algorithm> 

int* array = new int[n]; // Assuming "n" is a pre-existing variable

std::fill_n(array, n, 0); 

But be aware that under the hood this is still actually just a loop that assigns each element to 0 (there's really not another way to do it, barring a special architecture with hardware-level support).

但请注意,在幕后,这实际上仍然只是一个将每个元素分配为 0 的循环(实际上没有其他方法可以做到,除非具有硬件级支持的特殊体系结构)。

回答by mloskot

There is number of methods to allocate an array of intrinsic type and all of these method are correct, though which one to choose, depends...

分配固有类型数组的方法有很多种,所有这些方法都是正确的,但选择哪一个取决于...

Manual initialisation of all elements in loop

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

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

Using std::memsetfunction from <cstring>

使用std::memset函数来自<cstring>

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

Using std::fill_nalgorithm from <algorithm>

使用std::fill_n算法来自<algorithm>

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

Using std::vectorcontainer

使用std::vector容器

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

If C++0xavailable, using initializer listfeatures

如果C++0x可用,使用初始化列表功能

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

回答by John Dibling

If the memory you are allocating is a class with a constructor that does something useful, the operator new will call that constructor and leave your object initialized.

如果您分配的内存是一个带有构造函数的类,该类可以做一些有用的事情,那么操作符 new 将调用该构造函数并使您的对象保持初始化状态。

But if you're allocating a PODor something that doesn't have a constructor that initializes the object's state, then you cannot allocate memory and initialize that memory with operator new in one operation. However, you have several options:

但是,如果您正在分配一个POD或没有构造函数来初始化对象状态的东西,那么您将无法分配内存并在一次操作中使用运算符 new 初始化该内存。但是,您有多种选择:

1) Use a stack variable instead. You can allocate and default-initializein one step, like this:

1)改用堆栈变量。您可以一步分配和默认初始化,如下所示:

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

2) use memset(). Note that if the object you are allocating is not a POD, memsetting it is a bad idea. One specific example is if you memset a class that has virtual functions, you will blow away the vtable and leave your object in an unusable state.

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

3) Many operating systems have calls that do what you want - allocate on a heap and initialize the data to something. A Windows example would be VirtualAlloc()

3)许多操作系统都有做你想做的调用 - 在堆上分配并将数据初始化为某些东西。Windows 示例是VirtualAlloc()

4) This is usually the best option. Avoid having to manage the memory yourself at all. You can use STL containers to do just about anything you would do with raw memory, including allocating and initializing all in one fell swoop:

4) 这通常是最好的选择。完全避免必须自己管理内存。你可以使用 STL 容器来做任何你可以用原始内存做的事情,包括一举分配和初始化:

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

回答by villintehaspam

Yes there is:

就在这里:

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

Use a vector instead of a dynamically allocated array. Benefits include not having to bother with explicitely deleting the array (it is deleted when the vector goes out of scope) and also that the memory is automatically deleted even if there is an exception thrown.

使用向量而不是动态分配的数组。好处包括不必理会显式删除数组(当向量超出范围时将其删除),并且即使抛出异常,内存也会自动删除。

Edit: To avoid further drive-by downvotes from people that do not bother to read the comments below, I should make it more clear that this answer does not say that vector is alwaysthe right answer. But it sure is a more C++ way than "manually" making sure to delete an array.

编辑:为了避免那些懒得阅读下面评论的人的进一步下车投票,我应该更清楚地说明这个答案并没有说向量总是正确的答案。但它肯定是比“手动”确保删除数组更 C++ 的方式。

Now with C++11, there is also std::array that models a constant size array (vs vector that is able to grow). There is also std::unique_ptr that manages a dynamically allocated array (that can be combined with initialization as answered in other answers to this question). Any of those are a more C++ way than manually handling the pointer to the array, IMHO.

现在在 C++11 中,还有 std::array 模型一个恒定大小的数组(vs 能够增长的向量)。还有 std::unique_ptr 管理动态分配的数组(可以与此问题的其他答案中回答的初始化相结合)。任何这些都是比手动处理指向数组的指针更 C++ 的方式,恕我直言。

回答by villintehaspam

std::fillis one way. Takes two iterators and a value to fill the region with. That, or the for loop, would (I suppose) be the more C++ way.

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

For setting an array of primitive integer types to 0 specifically, memsetis fine, though it may raise eyebrows. Consider also calloc, though it's a bit inconvenient to use from C++ because of the cast.

将原始整数类型的数组具体设置为 0memset很好,尽管它可能会引起注意。还要考虑calloc,尽管由于强制转换,从 C++ 使用它有点不方便。

For my part, I pretty much always use a loop.

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

(I don't like to second-guess people's intentions, but it is true that std::vectoris, all things being equal, preferable to using new[].)

(我不喜欢猜测人们的意图,但确实如此,std::vector在所有事情都平等的情况下,最好使用new[].)

回答by Gregor Brandt

you can always use memset:

您可以随时使用 memset:

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

回答by Paul Nathan

Typically for dynamic lists of items, you use a std::vector.

通常对于动态项目列表,您使用std::vector.

Generally I use memset or a loop for raw memory dynamic allocation, depending on how variable I anticipate that area of code to be in the future.

通常,我使用 memset 或循环进行原始内存动态分配,具体取决于我预计该代码区域在未来的变化程度。