在 C++ 中的函数内更改二维数组的值

Altering values of a 2D array inside a function in C++

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

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

但是,这怎么能用 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); 

}

正如 spug 所说,内存并没有被释放,你只是丢失了指针。您需要通过引用传递它:

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

我建议永远不要在 C++ 中使用多维数组,除非您真的需要指向指针的指针。一种更简单、更安全的方法是围绕大小为 x*y 的一维数组创建包装器 class,然后定义函数或运算符,使您能够通过指定 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];
    }
};

此解决方案还有一个额外的好处,即通过线性和紧密打包的方式存储内容,对缓存更加友好。

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

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