是否可以在C ++中动态创建一个常量大小的数组?

时间:2011-03-17 13:52:23

标签: c++ arrays new-operator

首先,我想向大家保证,我出于好奇而问这个问题。我的意思是,不要告诉我,如果我需要这个,那么我的设计有问题,因为我不需要在实际代码中。希望我说服你:)现在问题:

对于大多数类型T我们可以写

T* p = new T;

现在如果T是数组类型怎么办?

int (*p)[3] =  new ???; //pointer to array of 3 = new ???

我试过了:

typedef int arr[3];
arr* p = new arr;

但这不起作用。

是否有任何有效的语法,或者在C ++中是不可能的。如果不可能,为什么呢?感谢

编辑 :我猜我不够清楚。我希望能够在这种情况下使用它:

void f(int(&)[3]);
int (*p)[3] = new ???;
f(*p);

4 个答案:

答案 0 :(得分:11)

要从new获取指向数组的指针,您必须动态分配一个二维数组:

int (*p)[3] = new int[1][3];

答案 1 :(得分:10)

你不能这样做的原因是new int[3]已经准确地分配了你想要的类型int[3]的对象。只是new-expression 返回的内容是指向其第一个元素的指针。 5.3.4 / 1:

  

如果实体是非数组对象,   new-expression返回一个指针   到创建的对象。如果是的话   数组,new-expression返回一个   指向初始元素的指针   阵列。

返回指向第一个元素的指针是允许3在运行时被识别的原因,所以我想通过提前知道它,你已经超过了你没有使用的灵活性。

我想解决这个问题的方法是将reinterpret_cast重新解释为你想要的指针类型(不一定是可移植的),或者分配一个包含int[3]的结构(并使用指向其数据成员的指针)。

[编辑:呃,是的,或FredOverflow的想法,既没有劣势,但需要使用delete[]代替delete。]

我想道德是,如果你编写的模板天真地用T分配一些未知类型new,那么当有人将数组类型作为T传递时,模板将不起作用。你将它分配给错误的指针类型,如果你修复它(可能是auto),你将错误地删除它。

编辑回答j_kubik的问题:

这是区分数组和非数组类型的一种方法。如果您编写这样的函数,它返回一个包含指针的对象并能够正确删除它,那么您对任何类型T都有一个通用的新/删除。

#include <iostream>

template <typename T>
void make_thing_helper(T *) {
    std::cout << "plain version\n";
}

template <typename T, int N>
void make_thing_helper(T (*)[N]) {
    std::cout << "array version\n";
}

template <typename T>
void make_thing() {
    make_thing_helper((T*)0);
}

int main() {
    typedef int T1;
    typedef int T2[3];
    make_thing<T1>();
    make_thing<T2>();
}

答案 2 :(得分:2)

你总是可以使用boost :: array,它将在C ++ 0x中。 否则,任何解决方案充其量都是尴尬的:数组是 用C语言打破,C ++在这方面保持了与C的兼容性 尊重。 Fred Overflow提供了一个解决方案;更容易(但是 语法噪音)将数组包装在一个结构中:     struct A {int arr [3]; }; 并分配和操纵它。

答案 3 :(得分:-2)

你刚才

int *p = new unsigned int [3]

然后,您可以使用*p作为指针或数组,即*(p+1) or p[1]