2017-07-14 35 views
1

C++中用於初始化和改變使用int**聲明的二維整數數組的正確語法是什麼?在C++中改變函數內部二維數組的值

我正在使用下面的代碼,但由於內存在函數退出時被取消分配,我得到了意外的行爲,這當然是它的意圖。

但是,這怎麼能在C++中整齊地完成呢?我知道其他人也面臨類似的問題,但Is passing pointer argument, pass by value in C++?等問題太籠統。

void Insert_into_2D_Array(int** foo, int x_pos, int y_pos, int x_size, int y_size) 
{ 
    int insert_value = 10; 

    if (x_pos < x_size && y_pos < y_size) { 
    foo[x_pos][y_pos] = insert_value; // insert_value lost post func exit? 
    } 
} 

void Init_2D_Array(int** foo, int x_size, int y_size) 
{ 

    foo = new int*[x_size]; // new alloc mem lost post func exit ? 
    for (int i=0;i<x_size;i++) 
    { 
     foo[i] = new int[y_size];  // new alloc mem lost post func exit 
    } 
} 

int main(int agc, char** argv) 
{ 

    int** foo; 
    int x_size=10, y_size=10; 
    Init_2D_Array(foo, x_size, y_size); 
    Insert_into_2D_Array(foo, 3,3, x_size, y_size); 

} 
+0

當你調用'new'時,函數返回時內存不會被釋放。 – user463035818

+0

它沒有被釋放。你只是簡單地設置了指針'foo'的值,它是通過值*傳遞的。您需要在本地聲明'foo',或者在末尾傳遞'int *** foo'並解除引用。 – meowgoesthedog

+0

正如你所說,做'Init_2D_Array(foo)'按值傳遞它。要通過引用來傳遞它,語法應該是什麼? –

回答

1

as underscore_d suggest,correct way is using a std :: vector and pass references。

但是,如果你仍然想使用指針在你的代碼,

這裏

if (x_pos < x_size && y_pos < y_size) { foo[pos] = insert_value; // insert_value lost post func exit }

爲我工作的代碼是:

void Insert_into_2D_Array(int** foo, int x_pos, int y_pos, int x_size, int y_size) 
{ 
    int insert_value = 10000; 

    if (x_pos < x_size && y_pos < y_size) { 
    (foo)[x_pos][y_pos] = insert_value; // insert_value lost post func exit 
    } 
} 

void Init_2D_Array(int*** foo, int x_size, int y_size) 
{ 

    *foo = new int*[x_size]; // new alloc mem lost post func exit 
    for (int i=0;i<x_size;i++) 
    { 
     (*foo)[i] = new int[y_size];  // new alloc mem lost post func exit 
    } 
} 

void main(){ 

     int** foo = NULL; 
     int x_size=10, y_size=10; 
     Init_2D_Array(&foo, x_size, y_size); 
     Insert_into_2D_Array(foo, 3,3, x_size, y_size); 

     cout<<"############# "<<foo[3][3]<<endl; 
} 
+0

它應該是函數參數中的「int ** foo」嗎? –

+0

@dr_rk是的,它應該像int ** foo ..由壞的複製...!正在改變..! – AdityaG

1

像spug說的,內存不被釋放,你只是失去了指針。您需要按引用傳遞它:

void Init_2D_Array(int** & foo, int x_size, int y_size) 

我建議使用從未多維數組在C++中,除非你真的需要指針的指針。更簡單和更安全的方法是圍繞尺寸爲x*y的一維數組創建包裝類,然後定義函數或運算符,使您可以通過指定xy座標來訪問基礎元素。

class Array2D 
{ 
private: 
    int* m_array; 
    int m_sizeX; 
    int m_sizeY; 

public: 
    Array2D(int sizeX, int sizeY) : m_sizeX(sizeX), m_sizeY(sizeY) 
    { 
     m_array = new int[sizeX*sizeY]; 
    } 

    ~Array2D() 
    { 
     delete[] m_array; 
    } 

    int & at(int x, int y) 
    { 
     return m_array[y*sizeX + x]; 
    } 
}; 

該方案具有一個額外的好處更多的緩存友好的存儲線性和緊湊的內容。

1

首先,對於二維數組或任何其他多維數組,最好使用一維緩衝區作爲存儲,並且將一個項目作爲y * width + x;

但是對於你的特殊情況,如果你真的想使用它就像你有幾個問題。 在這裏你有固定的代碼。首先,在init函數中,我們不會取回新分配的指針。你傳遞給函數和地址,你將得到你傳遞給函數的相同地址。新分配的地址丟失。

void Insert_into_2D_Array(int** foo, int x_pos, int y_pos, int x_size, int y_size) 
{ 
    int insert_value = 10; 

    if (x_pos < x_size && y_pos < y_size) { 
     foo[x_pos][y_pos] = insert_value; // insert_value lost post func exit 
    } 
} 

int** Init_2D_Array(int x_size, int y_size) 
{ 

    int** foo = new int*[x_size]; // new alloc mem lost post func exit 
    for (int i = 0; i<x_size; i++) 
    { 
     foo[i] = new int[y_size];  // new alloc mem lost post func exit 
    } 

    return foo; 
} 

int main() 
{ 

    int** foo; 
    int x_size = 10, y_size = 10; 
    foo = Init_2D_Array(x_size, y_size); 
    Insert_into_2D_Array(foo, 3, 3, x_size, y_size); 

    return 0; 
} 
+0

您是否絕對確定'foo [x_pos] [y_pos] = insert_value;'將設置數組中的值,並且在函數退出後它不會丟失。 –

+0

是的。您可以在debbuger中嘗試它,或者在執行後打印結果。在插入時已經分配了緩衝區,您將foo的地址傳遞給函數Insert_into_2D_Array,並且最後您擁有相同的地址。你也分配了insert_position的值,所以在函數exit的這個變量被銷燬之後沒問題。 –