2011-02-18 27 views
1

我正在寫一個C++類,使用一些固定的數組,以及一些動態分配的數組。 我想知道是否有人可以指導我正確的方式爲動態數組分配內存,可能在構造函數/解構器中,以及如果我需要明確地調用它們以確保我沒有發生seg錯誤。 這裏是我的代碼的相關部分的簡化版本:正確的內存分配在一個類中的二維數組在C++

class Network { 

    public: 
    int n_nodes; 
    int user_index[MAX_USERS]; //a fixed array 
    int adjacency_matrix[][MAX_ITEMS]; 

    //Network(int n_node, int** adjacency); //I would rather to set the element s in a function other than the constructor 
    Initializer(int n_node, int** adjacency); 
    ~Netowrk(); 
    } 

因此,這裏是我對這個類具體問題:

1 - 我能有二維數組adjacency_matrix [] []與未定直到用戶在初始化函數中設置它的行數和列數?

2 - 我應該在哪裏刪除二維數組?我應該把它寫在解構器中嗎?我應該明確調用拆解器嗎?我還需要在解構器中銷燬什麼?

+0

Dupe? http://stackoverflow.com/questions/2294338/c-2d-dynamic-array –

回答

2

1 - 我可以有二維數組adjacency_matrix[][]未定的行數和列數,直到它由初始化函數中的用戶設置?

是的。但是,最好的方法是不使用數組。相反,使用std::vector,它爲您管理內存。有兩種方法可以做到這一點。如果你真的希望能夠使用[row][column]語法訪問元素,你需要使用的std::vector的兩個維度:

std::vector<std::vector<int> > adjacency_matrix; 

一旦你知道尺寸,你可以填充它:

adjacency_matrix.assign(rows, std::vector<int>(columns)); 

使用包含所有元素的一維數組(或std::vector<int>)並使用row * row_count + column來訪問索引爲(row, column)的元素通常更容易。這樣,動態分配就會減少。你可以將訪問元素的邏輯包裝成幾個輔助函數。

2 - 我應該在哪裏刪除二維數組?我應該把它寫在解構器中嗎?

如果您使用std::vector,則不需要delete任何東西。它清理自己。

我應該明確調用[析構函數]嗎?

還有什麼我需要在[析]毀滅?

理想的是,沒有。如果您使用標準庫容器,如std::vector和智能指針,則不必清理任何東西。你應該避免試圖用C++自己管理資源:有庫設施可以爲你完成這項乏味的任務,你應該利用它們。

0

1 - 我可以使用具有未定數目的行和列的2D數組adjacency_matrix [] [],直到它在初始化函數中由用戶設置爲止嗎?

是的你可以。例如:

int* adjacency_matrix_; 
    int* getAdjacency(int i, int j) 
    { 
     if (!adjacency_matrix_) 
      return 0; 
     else 
      return adjacency_matrix_ + i*n_nodes + j; 
    } 
    Network() 
     : n_nodes(0), 
     adjacency_matrix_(0) 
    {} 
    void Initializer(int n_node, int** adjacency) 
    { 
     adjacency_matrix_ = new int[n_nodes * n_nodes]; 
     // Copy over data. 
    } 

至於是否你應該,這取決於你是否有不使用std::vector<>的理由。

2 - 我應該在哪裏刪除二維數組?我應該把它寫在解構器中嗎? 我應該明確調用拆解器嗎? 還有什麼我需要在解構器中銷燬?

是的,在使用析構函數數組運算符刪除絕對免費:

~Network() 
    { 
     delete [] adjacency_matrix_; 
    } 

不,每當網絡對象本身超出範圍的析構函數會被調用。很少有必要做一個明確的析構函數調用。不,所有析構函數需要顯式釋放的是你明確獲取的任何東西。

0

您可能喜歡的示例矩陣I類an answer to another question

本身爲約良好C++的設計實踐的問題寫到,但所選擇的例子是一個多維數組。

0

有幾種方法可以做到這一點。

最簡單的方法是使用矢量,如果你不喜歡管理自己的記憶,這對你來說是完美的。但是,因爲我喜歡管理自己的記憶,而且我發現這種方法有時很慢,很麻煩,所以我學到了其他方法。

最快的方法是分配一維數組並將其當作二維數組處理。這裏有一個例子:

int *array = new int[width*height]; 

int get_array(int column, int row) 
{ 
    return array[row*width + column]; 
} 

delete [] array; 

這可以推廣到n個維度:

int *array = new int[w1*w2*...*wn]; 

int get_array(int i1, int i2, ..., int in) 
{ 
    return array[in*(w1*w2*...*w(n-1)) + i(n-1)*(w1*w2*...*w(n-2)) + ... + i2*w1 + i1]; 
} 

delete [] array; 

如果你希望能夠有不同寬度的每一行,那麼你可以讓數組指針。此解決方案初始化和清理速度較慢,但​​靈活,可調,且執行時間相對較快。如果你犯了一個錯誤,它也可能是非常危險的。

int **array = new int*[height]; 

for (int i = 0; i < height; i++) 
    array[i] = new int[width(i)]; 

此時,訪問它,所有你需要做的就是習慣

array[i][j] 

然而,釋放這個數組,你必須這樣做逐行

for (int i = 0; i < height; i++) 
    delete [] array[i]; 

delete [] array; 

這也可以概括爲第n維。

int **....*array = new int**...*[w1]; 

for (int i1 = 0; i1 < w1; i1++) 
{ 
    array[i1] = new int**..*[w2]; 
    for (int i2 = 0; i2 < w2; i2++) 
    { 
      array[i1][i2] = new int**.*[w3]; 
      ... 
      for (int in = 0; in < wn; in++) 
       array[i1][i2]...[in] = new int[wn]; 
    } 
} 

for (int i1 = 0; i1 < w1; i1++) 
{ 
    for (int i2 = 0; i2 < w2; i2++) 
    { 
      ... 
      for (int in = 0; in < wn; in++) 
       delete [] array[i1][i2]...[in]; 
      ... 
      delete [] array[i1][i2]; 
    } 
    delete [] array[i1]; 
} 

delete [] array; 

這種設置往往會對內存造成嚴重破壞。只是這些的二維數組會導致寬度+1的獨立數組被malloc編輯。只需malloc一個大數組並且自己計算索引就會更快。

相關問題