【问题标题】:What is causing this runtime error while passing arrays on the heap between functions, c++在函数之间的堆上传递数组时导致此运行时错误的原因,c++
【发布时间】:2013-04-09 06:31:25
【问题描述】:

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

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

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

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

【问题讨论】:

  • 尝试通过引用将matrix 指针传递给matrix_malloc (int **&amp; matrix)

标签: c++ pointers multidimensional-array heap-memory


【解决方案1】:

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

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

这接受矩阵的副本。这意味着您在matrix 上的matrix_malloc 中所做的任何事情都不会影响main 中的那个。

应该是

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

【讨论】:

  • 谢谢你提供vector使用的例子,我需要学习如何使用这个。
  • @Leonardo 是的。确实。它让生活变得更轻松:)
【解决方案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];

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

【讨论】:

  • 你会怎么做,把&amp;改成另一个*
【解决方案3】:

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

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

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

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

int** matrix_malloc(int m, int n)

最后,您是否有理由不为此使用std::vector

【讨论】:

  • 我还没有研究如何使用这个向量,我会最终看到它以及为什么它会是一个好的情况。
【解决方案4】:

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

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

【讨论】:

  • 这很有趣,但是你看我是否有一个指向双指针并通过地址传递的指针,它不会起作用。
  • 当然,您必须相应地修改您的 matrix_malloc。我将编辑我的答案来说明。
  • 啊,我没有意识到我需要强制取消引用运算符的优先级,这就是它不起作用的原因。很高兴知道这一点。此外,使用这种方法似乎是个坏主意,因为如果我想再次通过指针传递到该方法中的函数怎么办?或者这不太可能,因为它是一个指针并且可以复制地址。
  • 这将始终取决于您是否要修改 pointed 数据(涉及[]* 的任何内容,在这种情况下您只需复制指针本身(@ 987654326@)) 或指针所在的位置(如果没有[]* - 如果您希望继续修改,则需要传递指针的地址(int*** ))。这种方法是否好是另一个争论 - 但在 C++ 中,您有很多工具可以避免这种头痛。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-26
  • 2016-08-05
  • 1970-01-01
  • 2016-11-20
  • 2022-07-11
  • 2015-09-22
  • 2018-01-11
相关资源
最近更新 更多