0

当我在接受双指针的函数之间传递在堆上声明的二维数组时,我无法解释为什么我的程序会挂起和崩溃。

我有一种强烈的感觉,它与我选择声明二维数组的方法有关。在我创建一个函数来分配数组之前,程序可以在传递给函数时操作数组内的数据。

所以这里是分配函数,然后是它在内部崩溃的函数:

void matrix_malloc(int **matrix, int m, int n);
void matrix_init(int **matrix, int m, int n);

int main(void)
{
  int **matrix;
  int m(3), n(2);

  matrix_malloc(matrix, m, n);
  matrix_init(matrix, m, n); // runtime error
}

void matrix_malloc(int **matrix, int m, int n)
{ // get heap memory
  int i;
  matrix = new int*[m];
  for(i = 0; i < m; i++)
  {
    matrix[i] = new int[n];
  }
}

void matrix_init(int **matrix, int m, int n)
{ // randomize matrix
  int i, j;
  for(i = 0; i < m; i++)
  {
    for(j = 0; j < n; j++)
    {
      matrix[i][j] = rand() % 10 + 1;
    }
  }
}
4

4 回答 4

2
void matrix_malloc(int **&matrix, int m, int n);
void matrix_init(int **matrix, int m, int n);

void matrix_malloc(int **&matrix, int m, int n)
{ // get heap memory
  int i;
  matrix = new int*[m];
  for(i = 0; i < m; i++)
  {
    matrix[i] = new int[n];
  }
}

并且应该运作良好。问题,因为在这之后

matrix = new int*[m];

矩阵有新地址,但由于它是指针的本地副本 - main 不知道它。

于 2013-04-09T06:33:42.610 回答
2

matrix_malloc()需要通过引用获取指针:

void matrix_malloc(int **&matrix, int m, int n)
                         ^

没有这个,新分配的指针不会传播回调用者。

也就是说,从函数返回新分配的指针可能更明确:

int** matrix_malloc(int m, int n)

最后,你不使用std::vector这个有什么原因吗?

于 2013-04-09T06:33:48.830 回答
2

您必须通过引用传递矩阵指针。

void matrix_malloc(int **matrix, int m, int n)

这接受矩阵的副本。这意味着您在其中所做的任何事情都不会matrix_malloc影响.matrixmain

相反,它应该是

void matrix_malloc(int **& matrix, int m, int n)
                        ^^^

但是我建议你使用向量而不是原始指针和分配。这样您就不必担心分配和解除分配。

void matrix_malloc(vector<vector<int> >& matrix, int m, int n);

// You don't need this anymore.
// void matrix_init(int **matrix, int m, int n);

int main(void)
{
  vector<vector<int> > matrix;
  int m(3), n(2);

  // matrix_malloc(matrix, m, n);

  matrix_init(matrix, m, n); 
}


void matrix_init(vector<vector<int> >& matrix, int m, int n)
{ // randomize matrix
  int i, j;
  for(i = 0; i < m; i++)
  {
    vector<int> row;
    for(j = 0; j < n; j++)
    {
      row.push_back(rand() % 10 + 1);
      // matrix[i][j] = rand() % 10 + 1;
    }
    matrix.push_back(row);
  }
}
于 2013-04-09T06:33:50.173 回答
1

二维数组的分配很好。但。

  int **matrix;
  int m(3), n(2);

  matrix_malloc(matrix, m, n);

在这里,矩阵不会改变 - 您正在复制它的值以将其传递给函数。我的意思是:

  int **matrix = NULL; // matrix points to null
  int m(3), n(2);

  matrix_malloc(matrix, m, n); // copy the value contained in matrix and give it to the function
  //matrix still points to null

您有多种解决方案:

  • 您的矩阵 malloc 可以返回一个 int**,您只需编写 matrix = matrix_malloc(m, n)
  • 您的矩阵 malloc 可以将指针指向 int** (int*** - 小心处理)
  • 正如其他答案中提到的,对 int** 的引用

这是带有 int*** 的 matrix_malloc 的样子。

//call it as follows:
matrix_malloc(&matrix, m, n);


void matrix_malloc(int ***matrix, int m, int n)
{
  // matrix contains the address of the original variable, so *matrix is the original variable itself.
  int i;
  *matrix = new int*[m];
  for(i = 0; i < m; i++)
  {
    (*matrix)[i] = new int[n];
  }
}
于 2013-04-09T06:35:32.287 回答