2010-02-19 181 views
3

我想动态分配一个2d数组到一个构造函数初始化中的指针。C++二维动态数组

FooBar::FooBar() 
    : _array(new int[10][10]) 
{ } 
int **_array; 

但这不起作用。我知道多维数组的分配有点不同。有没有人可以用解释来阐述这一点?

在此先感谢。

+1

嗨。 C++中的动态多维数组很丑陋。如果你真的在使用它们(而不是学习/作业),请看看boost多数组类型。 – Anycorn 2010-02-19 06:00:33

回答

3
int **array = new int *[10]; 

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

如果您使用的是新建的,则需要分别分配第二个维度的每一部分。

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

哎呀,有人先到这里。 – TachyonImpact 2010-02-19 05:57:56

4

C中的2维数组是指向其他数组的指针数组。

假设我们有3×3阵列a(类型int**):

a[0] (a[0] is of type int*) = [0][1][2] 
a[1] (a[1] is of type int*) = [0][1][2] 
a[2] (a[2] is of type int*) = [0][1][2] 

这意味着,需要两个分配通行证,一个用于指针数组,(INT **),其余是为该数组元素的每个

第一关,分配指针数组:

int** a = new int*[10]; 

第二遍,对每个a的的元素,分配一个新的数组:

for(int i=0; i<10; ++i) 
    a[i] = new int[10]; 

这会给你一个“二'C维数组。

正如你可以看到,这可能是在更高维度相当笨重,所以另一个关键是要分配10个* 10个元素,并使用阵列作为2D(又名“投影”):

const int ARRAY_WIDTH = 10; 
const int ARRAY_HEIGHT = 10; 
int* a = new int[ARRAY_WIDTH * ARRAY_HEIGHT]; 

    // To access a[5][2] you would use: 
a[5 + (2 * ARRAY_WIDTH)] = 0; 
+1

-1 - C/C++中的二维数组与指向数组的指针数组不一样,也没有指针类型。 – 2010-02-19 16:51:00

+0

-1,没有C/C++这样的语言。 – LiraNuna 2010-06-22 23:50:17

+0

-1 LiraNuna的回答不正确。编译器将C/C++中的2D(或n维)数组展平。维数[n] [m]的二维数组实际上是维数[n * m]的线性数组,并且[i] [j]的访问实际上是[i * m + j]的访问。 – KomodoDave 2011-09-30 19:39:48

7

某些答案这里说一个2维数组是指向其他数组的指针数组。这不是真的(如果你分配的只是数组的数据,那么存储指针的位置!?)。相反,二维数组是其他数组的数组。因此,你必须改变你的会员类型:

FooBar::FooBar() 
    : _array(new int[10][10]) 
{ } 
int (*_array)[10]; 

这是因为new[]返回一个指针,以创建数组的第一个元素。该元素是一个由10个整数组成的数组,因此成员类型发生变化。如果语法吓到你了,用temlate简化它(这个模板相当于boost::identity)。

template<typename T> struct identity { typedef T type; }; 

FooBar::FooBar() 
    : _array(new int[10][10]) 
{ } 
identity<int[10]>::type *_array; 

这有效地工作就像就地typedef。当然,就像使用new[]一样,它需要一个合适的delete[]放置在析构函数中,并在对象被销毁时调用。

由于new[]分配了一个编译时已知类型的元素数组,因此只能将第一个(最外层)维设置为运行时值 - 其他所有维在编译时必须具有已知值。如果这不是你想要的,你将不得不分配一个指针数组,就像其他答案说的那样。

但请注意,为避免进一步混淆,请注意那些是而不是多维数组。它们是指向其他一维数组的指针的单维数组。

0

如果你不关心性能多,你可以使用以下命令:

//vec2d.h 
#include<vector> 

template<class T> 
void init2DVect(std::vector< std::vector<T> >& _T, size_t sx, size_t sy) 
{ 
    _T.resize(sx); 
    for(size_t i =0; i < sx; ++i) 
    { 
    std::vector<T> ins_v(sy); 
    _T[i] = ins_v; 
    } 
} 

例用例:

//file: vec2d_test.cpp 
#include "vec2D.h" 

#include<cassert> 

int main() 
{ 
    std::vector< std::vector<int> > vi; 
    size_t sx = 5; 
    size_t sy = 7; 
    init2DVect(vi, sx, sy); 

    for(size_t i = 0; i < sx; ++i) 
    { 
    for(size_t j = 0; j < sy; ++j) 
    { 
     vi.at(i).at(j) = i*j; 
    } 
    } 

    for(size_t i = 0; i < sx; ++i) 
    { 
    for(size_t j = 0; j < sy; ++j) 
    { 
     assert(vi.at(i).at(j) == i*j); 
     assert(vi[i][j] == i*j); 
    } 
    } 

    return 0; 
} 

这样做,你不必担心优势关于内存,你可以使用vector :: at()函数为了抛出一个异常,如果你超出了界限......对C++作业很好,但是一个std :: vector向量并不是最快的方法去做吧。

不然的话,TNT library会诀窍。