这个函数实际上在做什么? int *array = new int[n];

30

我对如何创建动态定义的数组感到困惑:

 int *array = new int[n];

我不知道这段代码在做什么。我能看出它创建了一个名为array的指针,指向一个新的对象/数组int? 有人愿意解释一下吗?


我认为这是一个基本问题,但现代C++书籍/课程可能不再解释关键字“new”,我实际上有点喜欢这个... - MatG
8个回答

39

new 分配了存储所需对象/数组所需的内存。在这种情况下,是 n 个 int 类型的数字。

指针将存储该块内存的地址。

但要小心,分配的内存块直到您编写释放代码之前都不会被释放。

delete [] array;

1
我能否建议您将此编辑为类似于“但是您应该使用std::vector<int>array(5);,因为这是在C ++中创建此类对象的正确方法”。 - Aaron McDaid
因为,例如,如果函数提前返回(例如抛出异常),那么delete将不会被调用。基本上,在现代C++中,普通开发人员不应该显式地使用new(也不要使用delete)。 - Aaron McDaid
1
@AaronMcDaid:现代的异常安全版本应该是:std::unique_ptr<int[]> array{new int[n]};,而std::vector不仅仅是代码示例的异常安全版本。 - Ben Voigt
我的观点不是说vectorint [n]完全相同。如果我们假设我们想要对原始问题进行异常安全的回答,我们只有两个选择:unique_ptr<int[]>vector<int>。前者可能更“纯粹”,但我相信我们大多数人(包括你?)都会使用vector来解决提问者现在面临的实际问题。我们不知道他们当前编程任务的全部上下文——但可以肯定的是,vector是我们大多数人会使用的解决方案。 - Aaron McDaid

13
int *array = new int[n];

它声明了一个指向类型为int、大小为n的动态数组的指针。

更详细的答案: new 分配了一块大小等于sizeof(int) * n字节的内存,并返回由变量array存储的内存。此外,由于是使用new动态分配的内存,当你不再需要它时,应该手动释放它,方法是写入:

delete []array;
否则,你的程序将会泄露至少 sizeof(int) * n 字节的内存(取决于实现时采用的分配策略,泄露的空间可能更多)。

2
不,它不会用零初始化内存。而且 array 实际上是一个指向 int 的指针,而不是数组。内存泄漏至少将是你提到的大小,但很容易会更大。 - user2100815
6
C++语言的参考资料是C++标准,而不是你编写的某段代码,这段代码恰好支持你的说法。 - user2100815
1
s5.3.4/15 表示“如果没有进行初始化,则对象具有不确定的值”。第8.5节指定了默认的初始化规则,对于没有显式初始化的数组,每个元素都会被默认初始化。对于 int(显然没有构造函数)的默认初始化是“不执行初始化”。因此,int 数组是不确定的。因此,我认为你的论点是不正确的,@Nawaz。 - paxdiablo
3
@unapersson,虽然它可能会分配比那更多的内存,但是如果您不调用未定义的行为,就不能使用其中的任何额外内存。因此,就您而言,您应该假定您只拥有您要求的那么多内存。您会遇到问题的唯一情况是如果您进行了大量小的分配,以致浪费很高。 - paxdiablo
1
@paxdiablo 我最初的观点是关于 Nawaz 所说的泄漏内存的数量,而不是访问该内存的合法性或其他方面。 - user2100815
显示剩余8条评论

12

该语句基本上执行以下操作:

  1. 创建一个包含'n'个元素的整型数组
  2. 在进程的HEAP内存中分配内存,因为您使用new运算符创建指针
  3. 返回一个有效地址(如果在执行此语句时所需大小的内存分配可用)

2

new运算符会为一个由n个整数组成的块分配空间,并将该块的内存地址赋给变量array,其类型为int*

对于一维数组,new的一般形式如下:

array_var = new Type[desired_size];

2

它在堆上分配了一个大小为N的整数数组的空间,并返回一个指向它的指针,该指针被赋值给名为“array”的int*类型指针。


1

它根据n的值分配了那么多的空间,指针将指向数组即数组的第一个元素

int *array = new int[n];

0

从C++11开始,使用std::unique_ptr(仍然使用类似的结构)是一种内存安全的方法来实现这一点:

std::unique_ptr<int[]> array(new int[n]);

这将创建一个智能指针,指向一个足够大的内存块,可以容纳n个整数,并在超出范围时自动删除自身。这种自动清理很重要,因为它避免了您的代码提前退出并永远不会到达delete [] array;语句的情况。

另一种(可能更好的)选择是使用{{link1:std::vector}},如果需要具有动态调整大小功能的数组。当您需要不知道需要多少空间时,这非常有用,但它也有一些缺点(添加/删除元素的时间不是恒定的)。您可以创建一个数组,并使用类似以下内容的方式向其添加元素:

std::vector<int> array;
array.push_back(1);  // adds 1 to end of array
array.push_back(2);  // adds 2 to end of array
// array now contains elements [1, 2]

0
在C/C++中,指针和数组(几乎)是等价的。 int *a; a[0];将返回*a,而a[1];将返回*(a + 1) 但是数组不能改变它所指向的指针,而指针可以。 new int[n]将为“数组”分配一些空间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接