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

问题描述:

首先,我想让大家放心,因为我好奇地问了这个问题。我的意思是,不要告诉我,如果我需要这个,那么我的设计就会有问题,因为我不需要真正的代码。希望我相信你现在:)的问题:是否可以在C++中动态创建一个常量大小的数组?

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

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); 
+0

如果我理解正确的话,你想知道C++是否有一种方法来“推断”数组的大小,而不必在分配中明确指定它? – 2011-03-17 13:56:33

+0

@oakley:不太清楚:我问T是一个数组类型(具有编译时已知维数)时是否使用'T * p = mew T;'语法 – 2011-03-17 13:58:08

你不能这样做的原因是new int[3]已经准确地分配了你想要的东西,一个int[3]类型的对象。这就是新表达式返回,是指向其第一个元素的指针。 5.3.4/1:

如果实体是一个非阵列对象, 新表达式返回一个指针 到创建的对象。如果它是一个 数组,则新表达式会返回指向 数组的初始元素的 指针。

返回一个指向第一个元素是什么让3是未知的,直到运行时,所以我想通过知道它提前,你绊倒了,你是不是使用的灵活性。我想这种方法是reinterpret_cast回到你想要的指针类型(不一定是便携式),或分配一个包含int[3](并使用指向其数据成员的指针)的结构。

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

我猜的寓意是,如果你写的模板,天真地分配一些未知类型Tnew,那么当有人将数组类型传递为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>(); 
} 
+1

两个'新INT [3]'和'新INT [1] [3]'已被释放通过'delete []'。 – fredoverflow 2011-03-17 14:31:13

+1

@FredOverflow:的确,我的意思是“而不是”,非数组类型会发生什么,如果我正在发明Armen想要的魔法不存在的语法,那么要分配一个数组类型的单个对象*好像它是一个非数组类型,那么它会让你通过从'MagicNew'返回的同一个指针'delete'来删除它,所以它看起来像'typedef int arr [3]; arr * p = MagicNew arr; delete p;'我知道他没有在他的问题中指明这一点,也许我错误地认为其他人会以同样的方式创造它 – 2011-03-17 14:36:35

+0

所以总结 - 有没有办法新的删除模板准备好了阵列类型还是简直不可能? – 2011-09-06 06:22:06

你只是做

int *p = new unsigned int [3] 

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

+2

对不起,但这不是我所能问。在所有 – 2011-03-17 13:55:00

为了得到一个指针从new到数组,您必须动态分配一个二维数组:

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

嗯......不完全是我期待的,但我的例子肯定会工作...... +1 – 2011-03-17 14:02:12

你总是可以使用boost :: array,它将在C++ 0x中。否则,任何解决方案在最好情况下都会很尴尬:数组是 以C分解,而C++在此方面与C保持相容性。 Fred Overflow提供了一个解决方案;甚至更容易(但 句法噪声)将包装在结构中的数组:结构A {int arr [3]; }; 并分配和操作它。

+0

这将是一个解决方法,而不是解决方案:)而@弗雷德的也是,但至少我的例子与他的工作解决方法。与你的,它不会,是吗? – 2011-03-17 14:08:03

+1

包装是一种解决方法,但boost:array将是我的首选解决方案,用于处理固定大小的数组。所以奇怪,但可能的:空隙F(阵列 & p);阵列 * p值=新的数组; F(* P); – stefaanv 2011-03-17 14:39:07