【问题标题】:Dynamic Memory allocation during Transpose转置期间的动态内存分配
【发布时间】:2012-11-18 19:50:08
【问题描述】:

我正在尝试计算一个不是 n 乘 n 的矩阵的转置。 问题是我必须为要添加的每个元素分配新内存,我不必删除 **array。 代码就是这样。 // 初始化一个二维数组。

array  = new int*[row];
    for (int i=0; i<row; i++){
        arr[i] = new int[col]();
    }

现在我只考虑一种情况,假设我的矩阵是 3*4。矩阵的转置有 4*3 的暗淡。 我执行以下代码但它给出了“分段错误”。这个想法是我为将作为转置结果添加的元素分配一个新内存。 代码是:

int r=col;
int c=row;
 if (col<c){
  arr  = new int*[row];
  for (int i=col; i<=c; i++){
  arr[i] = new int[col](); // trying to allocate New Memory to elem.
  }

这里出错了。 任何帮助。另外,如果有任何其他方法可以解决此问题,请提出建议。

【问题讨论】:

  • 只需使用std::vector
  • +1 表示 Als,每次有人输入 * 时,计算机都会返回一个小的电压冲击。只是作为一个提醒。

标签: c++ matrix dynamic-memory-allocation


【解决方案1】:

编写一个带有访问器函数的包装器(例如,用于矩阵的 operator(row,col)),并在内部使用大小为 rows*cols 的一维数组。

它使事情变得更容易,并将此矩阵的数据保持在一起。这可以为较小的矩阵带来缓存优势。

这是您评论中要求的示例。它的目的非常简单,不使用任何模板。它使用向量作为内部存储。您可以使用 operator(..) 访问矩阵元素,例如

Matrix A(3,4);
// fill matrix
// you can access each element in a natural syntax as expected from math
int x = A(2,2);
A(2,2) = 3;

此外,您可能应该使用异常而不是断言来检查索引溢出。

// matrix.h
#include <vector>

class Matrix
{
public:
  Matrix(size_t rows, size_t cols);

  int& operator()(size_t row, size_t col);
  const int& operator()(size_t row, size_t col) const;

  int& operator[](size_t index);
  const int& operator[](size_t index) const;

  Matrix get_transposed() const;

  size_t compute_index(size_t row, size_t col) const;

  void print();

private:
  size_t  _rows;
  size_t  _cols;

  std::vector<int>  _data;

}; // class Matrix



// matrix.cpp 
#include "matrix.h"
#include <iostream>
#include <cassert>

Matrix::Matrix(size_t rows, size_t cols)
  : _rows(rows)
  , _cols(cols)
  , _data(rows*cols, 0)
{
}


int& Matrix::operator()(size_t row, size_t col)
{
  const size_t index = compute_index(row, col);
  assert(index < _data.size());
  return _data[index];
}

const int& Matrix::operator()(size_t row, size_t col) const
{
  const size_t index = compute_index(row, col);
  assert(index < _data.size());
  return _data[index];
}


int& Matrix::operator[](size_t index)
{
  return _data[index];
}

const int& Matrix::operator[](size_t index) const
{
  return _data[index];
}

size_t
Matrix::compute_index(size_t row, size_t col) const
{
  // here you should check that: 
  // row < rows
  // col < cols
  // and throw an exception if it's not
  assert(row<_rows);
  assert(col<_cols);

  return row * _cols + col;
}

Matrix
Matrix::get_transposed() const
{
  Matrix t(_cols,_rows); 

  for(size_t row = 0; row < _rows; ++row)
    for(size_t col = 0; col < _cols; ++col)
    {
      t(col,row) = (*this)(row,col);
    }
  return t;
}

【讨论】:

  • 你能否用更简单的方式和代码解释一下。我是初学者
【解决方案2】:

在您的第二个代码示例中,您覆盖了数组限制。 arrrow 元素的长度,从 0 计数到 row - 1。在 for 循环中,您的索引 icol 变为 c,这相当于 row 和数组之外的一个元素。正确的代码应该是 &lt; 而不是 &lt;=

for (int i=col; i < c; i++){
    arr[i] = new int[col](); // trying to allocate New Memory to elem.
}

除此之外,我建议您查看Wikipedia: Transpose,因为在您的第二种情况下,您可以使用第一个代码示例,只需切换行和列。

【讨论】:

  • @HardCode 如果你使用 std::array,那么就没有指针了。但我必须承认,这是个糟糕的建议。我刚刚意识到,std::array 不是动态的,而是静态的。因此,按照 cmets 中建议的方式使用 std::vector 可能是更好的选择。
  • 其实你能弄清楚我的代码有什么问题吗?我想我使用的概念必须有效。它是一个分配,我必须通过动态内存分配来实现它
  • @HardCode 这就是我在第一段中写的。我改写了它,希望现在更清楚。我还删除了关于 std::array 的部分,因为它不适用于您的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-23
  • 2013-11-06
  • 2012-01-13
  • 1970-01-01
  • 2021-02-15
  • 2013-07-01
相关资源
最近更新 更多