动态数组分配

时间:2015-01-12 11:52:50

标签: c++ arrays

我想知道为什么新的似乎没有保留数组信息并只返回一个int *:

#include <iostream>
using namespace std;

typedef int (*p_to_array)[80];
typedef int arr[80];




int main() 
{
   arr a;
   p_to_array p = &a;  //fine

   p_to_array p2 = new arr; // incompatible types 

   return 0;
}

3 个答案:

答案 0 :(得分:6)

我可能完全错了:(即这只是一个有根据的猜测)

new arr;

相当于:

new int[80];

按语言规则返回int*


来自cppreference.com :(感谢@interjay指出我实际上引用了无关的部分)

  

new-expression返回一个指向构造对象的prvalue指针,或者,如果构造了一个对象数组,则返回指向数组初始元素的指针。

我对此的理解是,在分配数组时,将选择new[]表单。你的例子唯一改变的是语法;它没有使语言将数组视为非数组(常规对象)。

答案 1 :(得分:4)

您可以使用数组语法或typedef-name来分配带new的数组 - 根据[expr.new] / 5允许和等效:

  

当分配的对象是一个数组时(即,   使用 noptr-new-declarator 语法或 new-type-id type-id   表示数组类型), new-expression 产生指向的数据   数组的初始元素(如果有)

如您所见,对于数组,只给出了指向初始元素的指针;不是指向数组对象本身的指针。因此,产生的类型为int*,而不是int (*)[N]

返回指向初始元素的指针的原因非常简单:它是您要使用的指针。
我们想写

auto p = new int[50];
// Or
int* p = new int[50];

以便能够使用普通的下标:

p[49] = 0xDEADBEEF;

如果p类型为int(*)[50]指向数组对象,那将是荒谬的,因为下标会将49 * 50 * 4添加到地址,而不只是49 * 4 - 因为下标语义和指针算法 我们必须使用两个下标:

p[0][49] = ...;

这是可怕的,不必要的多余。或者我们可以使用演员:

int* p = static_cast<int*>(new int[50]); // Or with auto

但这也很难看 为了避免这种麻烦,引入了这条规则。

答案 2 :(得分:1)

在此声明中

p_to_array p2 = new arr; // incompatible types 

初始值设定项new arr;的类型与变量p2

的类型不对应

初始化程序的类型是int *,初始化程序是指向已分配数组的初始元素的指针。根据typedef定义,变量p2的类型为int (*p_to_array)[80]

没有从int *类型到类型int (*p_to_array)[80]的隐式转换。所以编译器发出错误。

正确的声明可以查看以下方式

p_to_array p2 = new arr[1];