C++ 程序崩溃在:(1)矩阵乘法;(2)矩阵加减失败
简而言之,我的任务是创建一个动态分配内存以形成int值矩阵的类 类的一部分是执行基本矩阵计算(加法、减法和乘法)的成员函数。一切都可以编译(至少在我这方面),但当我使用驱动程序测试乘法部分时,它总是崩溃 我使用代码块作为我的IDE,但在尝试找出它时,调试器并没有给我带来太多的运气。计算似乎完成了(使用正确的值),但随后某个地方出现了可怕的错误 为清楚起见,矩阵类的每个对象都有以下成员数据:C++ 程序崩溃在:(1)矩阵乘法;(2)矩阵加减失败,c++,multidimensional-array,matrix-multiplication,dynamic-memory-allocation,C++,Multidimensional Array,Matrix Multiplication,Dynamic Memory Allocation,简而言之,我的任务是创建一个动态分配内存以形成int值矩阵的类 类的一部分是执行基本矩阵计算(加法、减法和乘法)的成员函数。一切都可以编译(至少在我这方面),但当我使用驱动程序测试乘法部分时,它总是崩溃 我使用代码块作为我的IDE,但在尝试找出它时,调试器并没有给我带来太多的运气。计算似乎完成了(使用正确的值),但随后某个地方出现了可怕的错误 为清楚起见,矩阵类的每个对象都有以下成员数据: private: int rows; int cols; int **elemen
private:
int rows;
int cols;
int **element;
下面是实现文件的一个片段,其中重载运算符*得到充实。在执行乘法的循环被注释掉之前,temp.element[i][x]被设置为“0”的部分,因为默认构造函数已经将所有值设置为“0”——我最初将其放入时忘记了这一点。当我没有把它注释掉的时候,它也不起作用
在测试中,我使用了一个2x3阵列和一个3x2阵列
Matrix Matrix::operator*(const Matrix &aMatrix) const
{
if(cols == aMatrix.rows)
{
Matrix temp(rows, aMatrix.cols);
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < aMatrix.cols; x++)
{
//temp.element[i][x] = 0;
for(int n = 0; n < cols; n++)
{
temp.element[i][x] += (element[i][n]
* aMatrix.element[n][x]);
}
}
}
return temp;
}
else
{
cerr << "Matrix multiplication failed -- incompatible matrix sizes."
<< endl;
return *this;
}
}
矩阵::运算符*(常数矩阵和aMatrix)常数
{
if(cols==aMatrix.rows)
{
矩阵温度(行、aMatrix.cols);
对于(int i=0;i cerr您需要弄清楚这些操作的语法和语义是什么。从您的示例来看,似乎您需要如下内容:
Matrix lhs = <something>;
Matrix rhs = <something>;
Matrix result = lhs * rhs;
矩阵lhs=;
矩阵rhs=;
矩阵结果=lhs*rhs;
“只工作”。虽然这在语法上可能很好,但您需要考虑如果lhs和rhs不能相乘(或添加,等等)会发生什么情况。您还需要担心结果设置是否正确。您不能只返回“由行数、列数和指针数组组成的结构”希望不会遇到可怕的内存管理问题
<>什么使产品消失?当它超出范围时?C++不是线性代数的一个很好的语言。< / P>
您需要做的第一个决定是,是否打算为无效操作抛出异常,或者向错误消息返回一些错误指示,可能是bool和const char*
然后,您可能应该尝试编写一个函数,其中包含一个结果引用和两个操作数引用,如果矩阵支持该操作,则只需正确处理基本代数即可。(我还没有提到,您的矩阵仅为整数矩阵。)
在“现实生活”中,您可能会试图找到一个管理所有这些的开源标准解决方案,因为数字操作需要非常小心地管理
甚至有人可能会说,这是一个几十年前用Fortran已经很好地解决了的问题,到今天,如果性能是一个问题,那么底层计算很有可能在Fortran中,或者是一个库,它是C的一个端口。您发布了一个复制构造函数和赋值操作符。Your分配操作员有4个主要问题:
您应该通过常量引用传递参数,而不是通过值传递参数
您应该返回对当前对象的引用,而不是一个全新的对象
如果new
在赋值过程中抛出异常,则表示您事先删除了内存,从而将对象弄乱了
它是多余的。相同的代码出现在复制构造函数中
您可以根据复制构造函数重写赋值运算符,并缓解这些问题:
#include <algorithm>
//...
Matrix& Matrix::operator=(const Matrix& aMatrix)
{
Matrix temp(aMatrix);
swap(*this, temp);
return *this;
}
void Matrix::swap(Matrix& left, Matrix& right)
{
std::swap(left.rows, right.rows);
std::swap(left.cols, right.cols);
std::swap(left.element, right.element);
}
因此,如果矩阵大小是一个问题,运算符+和+=将抛出一个异常。请注意运算符+
是如何根据+=
实现的。对*
、*=
、以及-
和-=
元素如何分配内存?是否应该检查f或者在做任何算术之前的维度?它是在默认构造函数中动态分配的。我用动态内存分配标记了这个问题,但没有包括>.<--不想让它陷入太多的代码。更具体地说,它默认为0x0,但接受两个参数分别定义行和列。@uber08-您正在按值返回一个矩阵。这意味着我们需要查看您的Matrix
用户定义的复制构造函数、赋值运算符和析构函数。它们在您发布的代码中都扮演着重要角色。@uber08-Matrix Matrix::operator=(Matrix aMatrix)
您应该按常量引用传递,而不是按值传递。此外,您应该返回一个引用,而不是一个全新的对象。它有很多错误,并且会导致问题。我无法想象有什么好的理由在出现错误的情况下返回操作的lhs。客户端代码可能注定会出现各种计算错误ns和关于标准错误的相应错误消息。作为一个实际问题,假设库拥有标准错误对客户端的开发人员来说可能是痛苦的。也许他们对标准错误有特定的想法。也许他们将其重定向到了类似/dev/null的位置。感谢您仔细查看。我一直在为发生了什么而苦苦挣扎一旦函数被调用,就只有这个玲珑的产品了……不幸的是,我被提供给我们的原型束缚在这个结构上。我会考虑你的其他建议。@uber08-正如上面的评论所述,你需要首先确保你的
Matrix::Matrix(const Matrix &aMatrix)
{
rows = aMatrix.rows;
cols = aMatrix.cols;
element = new int* [rows];
for(int i = 0; i < rows; i++)
{
element[i] = new int [cols];
for (int x = 0; x < cols; x++)
{
element[i][x] = aMatrix.element[i][x];
}
}
}
Matrix::~Matrix()
{
for(int i = 0; i < rows; i++)
{
delete [] element[i];
element[i] = NULL:
}
delete [] element;
element = NULL;
}
Matrix lhs = <something>;
Matrix rhs = <something>;
Matrix result = lhs * rhs;
#include <algorithm>
//...
Matrix& Matrix::operator=(const Matrix& aMatrix)
{
Matrix temp(aMatrix);
swap(*this, temp);
return *this;
}
void Matrix::swap(Matrix& left, Matrix& right)
{
std::swap(left.rows, right.rows);
std::swap(left.cols, right.cols);
std::swap(left.element, right.element);
}
Matrix& Matrix::operator+=(const Matrix &aMatrix)
{
if(rows != aMatrix.rows || cols != aMatrix.cols)
throw SomeException;
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < cols; x++)
element[i][x] += aMatrix.element[i][x];
}
return *this;
}
Matrix Matrix::operator+(const Matrix &aMatrix)
{
Matrix temp(*this);
temp += aMatrix;
return temp;
}