2010-02-19 183 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會訣竅。