正在删除模板化的C++二维数组
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
,但我发现这种方式比尝试分配和释放三维数组更方便。
当然,你需要检查这个方案是否足够快。我用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
;您可以使用CCD_ 10和CCD_。
关于向量的底层向量,使用相同的[i][j]
构造来解引用。它很容易与begin()
和end()
进行迭代。如果您绝对需要在某个例程中使用原始指针,那么您总是可以使用&row[0]
来访问它。
唯一可能的困难是无法轻松地将MatrixBody
转换为T**
。但请三思,也许您根本不需要使用T**
。
- 将值从二维数组输出到文本文件
- 在二维数组中查找最小值和最大值?
- 移动二维数组中的字符
- 如何正确填充在堆上分配的二维数组?
- 传递二维数组时出现问题
- 具有随机数的二维数组不会更改
- 如何在C++中获取二维数组中最少的一列数?
- 如何使用用户输入变量制作二维数组?
- C++ 中动态二维数组的访问冲突
- 遍历二维数组的所有子数组
- 将二维数组的所有元素插入到一维数组中
- 在函数中传递二维数组
- 为什么指针在对二维数组进行排序时无法正常工作?
- 创建 std::string 的二维数组的最佳做法
- 如何将文本文件读取到二维数组中并以 c++ 打印
- 元素在二维数组 c++ 中的出现次数
- 执行 c++ 二维数组
- C++ 中的二维数组初始化为一个值
- 在C++中初始化第一维大小未知的二维数组
- 如何在二维数组中存储值?