[英]Deleting templated C++ 2-dimensional array
对C ++在二维数组中传递维度的要求的烦恼使我开始研究一个模板化的Matrix类。 我已经在C#编写了一段时间,所以我确定我在这里有点生疏。
问题是,我一打到析构函数就得到一个堆异常,它试图删除二维数组。
感谢任何帮助!
template <typename T>
class Matrix {
public:
Matrix(int m, int n) : nRows(m), nCols(n) {
pMatrix = new T * [nRows];
for (int i = 0; i < nCols; i++) {
pMatrix[i] = new T[nCols];
}
}
~Matrix() {
if (pMatrix != NULL) {
for (int i = 0; i < nRows; i++) { delete[] pMatrix[i]; }
delete[] pMatrix;
}
}
T ** GetMatrix() const { return pMatrix; }
T * Row(int i) const { return pMatrix[i]; }
inline T Cell(int row, int col) const { return pMatrix[row][col]; }
inline int GetNRows() const { return nRows; }
inline int GetNCols() const { return nCols; }
private:
int nRows, nCols;
T ** pMatrix;
};
这是错误:
for (int i = 0; i < nCols; i++) {
pMatrix[i] = new T[nCols];
}
循环应该是nRows
,而不是nCols
。
除此之外,让我告诉你我厌倦了分配二维阵列时所做的事情。 我不得不做一个三维阵列。 我使用了一个从坐标映射的map
- 一个包含x,y,z的结构到我想要的类型。
我工作得很快,不需要分配或解除分配。 分配到坐标只是通过
mymap[Coord(x, y, z)] = whatever...
当然我需要定义Coord
结构并重载< operator
,但我发现这比尝试分配和释放3-d数组更方便。
当然,您需要检查此方案是否足够快。 我用它来使用OpenGL在一个大的立方体内绘制单元格,并且完全没有任何抱怨。
关于这个bug,@ CodeChords_man解释得对。 我有关于实施的说明。 我建议您浏览这篇精彩的常见问题解答帖子 。
除非您100%确定,否则不应使用动态内存分配
我不知道第一个,以及性能如何对您至关重要。 但至于第二个,你至少违反了三个规则 。 你上课是非常不安全的。 如果复制它,则会双重删除内存缓冲区。
您不应该害怕使用STL容器,它们快速且优化。 至少std::vector
,它在许多情况下和原始指针一样快。 您可以使用std::vector
重写您的类,如下所示:
template <typename T>
class Matrix {
public:
typedef std::vector<T> MatrixRow;
typedef std::vector<MatrixRow> MatrixBody;
Matrix(int m, int n) : nRows(m), nCols(n), _body(m, MatrixRow(n)) {}
const MatrixBody& GetMatrix() const { return _body; }
const MatrixRow& GetRow(int i) const { return _body[i]; }
inline T Cell(int row, int col) const { return _body[row][col]; }
inline int GetNRows() const { return nRows; }
inline int GetNCols() const { return nCols; }
private:
int nRows, nCols;
MatrixBody _body;
};
由于此类未使用动态内存分配,因此可以安全地进行复制和分配。 在这种情况下,您也不需要显式存储nRows
和nCols
; 你可以使用_body.size()
和_body[0].size()
代替。
关于向量的基础向量,使用相同的[i][j]
构造对其进行解引用。 它很容易用begin()
和end()
迭代。 如果您绝对需要在某个例程中使用原始指针,则始终可以使用&row[0]
访问它。
唯一可能的困难是你不能轻易地将MatrixBody
转换为T**
。 但想想它两次,也许你根本不需要使用T**
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.