重载的*运算符在多个*操作后调用析构函数时失败
overloaded * operator fails when calling destructor after multiple * operations
我正在为我正在运行的测试创建一个类来进行矩阵(和向量)数学运算,并学习更多C++。类看起来是这样的:
class utlMatrix
{
private:
int num_rows;
int num_cols; // number of columns
double **data; // array of pointers to the data
public:
// default constructor, with initialization
utlMatrix() : num_rows(0), num_cols(0), data(NULL) {};
// constructor with size
utlMatrix(int, int);
// destructor
~utlMatrix();
// copy constructor
utlMatrix(const utlMatrix&);
void copy(const utlMatrix &old); // copy 'old' to 'this'
void zero(); // sets all values to zero
void fill_rand(); //fills the data with random stuff
void print(std::ostream&); // prints the matrix to a file
// Operators
utlMatrix& operator=(const utlMatrix&); // copies matrices
friend utlMatrix operator+(const utlMatrix&, const utlMatrix&); // adds 2 matrices
utlMatrix operator*(const utlMatrix&) const;
//friend utlMatrix operator*(const utlMatrix&, const utlMatrix&); // multiplies 2 matrices
};
复制构造函数、赋值运算符和析构函数
// copy constructor
utlMatrix::utlMatrix(const utlMatrix &old) {
copy(old);
}
utlMatrix& utlMatrix::operator=(const utlMatrix &old) {
copy(old);
return *this;
}
void utlMatrix::copy(const utlMatrix &old) {
num_rows = old.num_rows;
num_cols = old.num_cols;
data = new float*[num_rows];
for (int i = 0; i < num_cols; i++)
data[i] = new float[num_cols];
for (int i = 0; i < num_rows; i++)
{
for (int j = 0; j < num_cols; j++)
data[i][j] = old.data[i][j];
}
}
utlMatrix::~utlMatrix()
{
for (int i = 0; i < num_rows; i++)
delete [] data[i];
delete [] data;
}
乘法运算符,我两次都试过了,如果连续使用两次,两次都失败了。
/*
utlMatrix operator*(const utlMatrix &left, const utlMatrix &right)
{
// first determine if the matrices can be multiplied
if (left.num_cols != right.num_rows)
{
std::cout << "Error using *, Inner dimensions must agree." << std::endl;
exit(-1);
}
// create the new matrix
utlMatrix newmat(left.num_rows, right.num_cols);
for (int i = 0; i < left.num_rows; i++)
for (int j = 0; j < right.num_cols; j++)
for (int k = 0; k < right.num_rows; k++)
newmat.data[i][j] += left.data[i][k] * right.data[k][j];
return newmat;
}
*/
utlMatrix utlMatrix::operator*(const utlMatrix &right) const
{
if ( this->num_cols != right.num_rows)
{
std::cout << "Error using *, Inner dimensions must agree." << std::endl;
return utlMatrix();
}
utlMatrix newmat(this->num_rows, right.num_cols);
for (int i = 0; i < this->num_rows; i++)
for (int j = 0; j < right.num_cols; j++)
for (int k = 0; k < right.num_rows; k++)
newmat.data[i][j] += this->data[i][k] * right.data[k][j];
return newmat;
}
复制构造函数、赋值运算符和加法运算符都可以正常工作。当我尝试将一个矩阵乘以另一个矩阵时,第一次有效,但第二次失败。除了在乘法运算后打印矩阵外,我还修改了代码,使其在进入构造函数、运算符和析构函数时写出。数学对第一个矩阵很好,代码失败:
Unhandled exception at 0x776015de in sandbox.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd.
从屏幕输出中,我知道这是在第二次乘法之后调用复制构造函数之后发生的。加法运算符反映了第一个乘法运算符,看起来工作得很好,没有例外,复制构造函数和析构函数按预期发生。我找到了关于SO的两个答案,矩阵类运算符重载,析构函数问题和带运算符重载的矩阵乘法。我检查了一下,以确保我的指针没有被复制。复制构造函数确实创建了一个带有指向数据的新指针的新对象。如果我运行:
int main()
{
utlMatrix A(3,3);
utlMatrix B(2,2);
A.fill_rand();
B.fill_rand();
B = A;
return 0;
}
调试器显示:
A {num_rows=3 num_cols=3 data=0x000365c0 ...} utlMatrix
B {num_rows=3 num_cols=3 data=0x00037c50 ...} utlMatrix
我错过了什么?以下是我实际使用运算符的方式。故障发生在D=A*B之后;
#include "utlMatrix.h"
int main()
{
// create the first matrices
utlMatrix A(3,3);
utlMatrix B(3,3);
utlMatrix C(3,2);
// fill them with random numbers
A.fill_rand();
B.fill_rand();
C.fill_rand();
utlMatrix D = A * B;
utlMatrix E = A * C;
utlMatrix F = B * C;
}
错误似乎只在第二次或第三次调用后出现,因为那是矩阵产生非平方输出的时候。这些线路:
for (int i = 0; i < num_cols; i++)
data[i] = new float[num_cols];
在复制构造函数中,意味着非方形矩阵实际上是作为旧矩阵的大小列的方形矩阵构建的。由于我的例子是一个行多于列的矩阵,所以它试图将数据放入不存在的内存位置。根据Igor Tandetnik和Dave S的建议,修复索引并使用SWAP解决了问题。
相关文章:
- 什么时候调用析构函数
- C++-明确何时以及如何调用析构函数
- C++ 防止在映射中放置()时调用析构函数
- 调用析构函数以释放动态分配的内存
- C++:使用方法调用析构函数的顺序是什么?
- 向量推回调用析构函数时调用析构函数
- 如何在调用析构函数时优雅地停止/销毁带有阻塞调用C++线程?
- C++,我应该调用析构函数吗?
- 如何获取有关在 Clang LibTooling 中调用析构函数的信息?
- 当我从 std::vector 中的新放置调用析构函数时会发生什么?
- 为什么这里不调用析构函数
- 在调用 std::bind 的产品后意外调用析构函数
- 为什么在传递给函数而不是构造函数时调用析构函数?
- 如何在C++中调用析构函数
- 为什么为未删除的对象调用析构函数?
- 调用析构函数时出错
- C++ 在不释放内存的情况下调用析构函数
- 为什么在运算符删除中不调用析构函数?
- C++ 调用析构函数后动态模板队列"double free or corruption (out)"
- 在 postOrderDelete 上调用析构函数时引发的异常