在C ++中改变函数内的2D数组的值

时间:2017-07-14 14:29:36

标签: c++ arrays pointers multidimensional-array

C ++中用于初始化和更改使用int**声明的2D整数数组的正确语法是什么?

我正在使用下面的代码,但由于在函数退出时取消分配内存,我得到了意外的行为,这当然是它的意思。

但是,如何在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); 

}

3 个答案:

答案 0 :(得分: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 :(得分:1)

作为underscore_d建议,正确的方法是使用std :: vector并传递引用。

但如果您仍想在代码中使用指针,

这里

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;
}

答案 2 :(得分:1)

首先,对于2D数组或任何其他多维数组,最好使用一维缓冲区作为存储,并将项目称为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;
}