为什么这是一个分割错误与这个代码片段?



这是我关于矩阵的代码(我决定练习OOP编写自己的矩阵类)

Matrix.hpp

#ifndef MATRIX_HEADER
#define MATRIX_HEADER
typedef unsigned int u_int;
class Matrix
{
double **mtrx;
u_int x, y;
public:
Matrix(u_int a, u_int b);
Matrix(const Matrix &);
~Matrix();
double det();
Matrix operator+(const Matrix &) const;
Matrix operator-(const Matrix &) const;                           
Matrix operator*(const Matrix &) const;
friend Matrix operator*(const Matrix &, const double &);
Matrix operator/(const Matrix &) const;
double *operator[](const u_int idx) const { return mtrx[idx]; }
bool IsEqual(const Matrix &) const;
u_int GetX() const { return x; }
u_int GetY() const { return y; }
};
#endif

Matrix.cpp

#include "Matrix.hpp"
Matrix::Matrix(u_int a, u_int b) : x(a), y(b)
{
mtrx = new double *[x];
for (u_int i = 0; i < x; i++)
mtrx[i] = new double[y];
}
Matrix::Matrix(const Matrix &ref)
{
if (mtrx)
{
for (u_int i = 0; i < x; i++)
delete[] mtrx[i];
delete[] mtrx;
}
x = ref.x;
y = ref.y;
*mtrx = new double[x];
for (u_int i = 0; i < x; i++)
mtrx[i] = new double[y];
}
Matrix::~Matrix()
{
if (mtrx)
{
for (u_int i = 0; i < x; i++)
delete[] mtrx[i];
delete[] mtrx;
}
}
bool Matrix::IsEqual(const Matrix &a) const     // If sizes of matrixes are equal
{                                               // matrixes are equal
return (a.GetX() == x) && (a.GetY() == y);
}
Matrix Matrix::operator+(const Matrix &a) const
{
if (!IsEqual(a))                            // Check on equality matrixes
return Matrix(1,1);                     // I have not any idea yet what          
Matrix matrix(x, y);                        // should it give is sizes 
for (u_int i = 0; i < x; i++)               // of Matrix are not equal
for (u_int j = 0; j < y; j++)
matrix[i][j] = a.mtrx[i][j] + mtrx[i][j];
return matrix;
}

main.cpp

#include <stdio.h>
#include "Matrix.hpp"
int main()
{
Matrix a(2, 5);
Matrix b(2, 5);
for (u_int i = 0; i < a.GetX(); i++)
{
for (u_int j = 0; j < a.GetY(); j++)
{
a[i][j] = i + j;
}
}
for (u_int i = 0; i < b.GetX(); i++)
{
for (u_int j = 0; j < b.GetY(); j++)
{
b[i][j] = i + j;
}
}
Matrix c = a + b;
return 0;
}

当我打开程序时,它在添加两个矩阵后抛出分割错误。在这种情况下,对我来说更有趣的是Matrix.cpp, Matrix Matrix::operation+...的前两行。

当我删除这2行(检查相等2矩阵)时,当我打开程序时,它不会给我一个分割错误,但是当我添加这2行时,程序会给我一个s.f。你能告诉我为什么它是这样工作的吗?

您可以考虑使用1Ddouble[x*y]阵列而不是double[y]阵列的2Ddouble*[x]。这将使内存管理更容易一些,因为您只需要处理一个数组,而不是多个数组。

在任何情况下,你的Matrix(const Matrix &)复制构造函数不应该是delete[]mtrx中的任何东西,因为mtrx还没有被初始化(它指向随机内存)。构造函数的其余部分也没有正确分配数组。您在Matrix(u_int, u_int)构造函数中正确地分配了数组,因此只需将该逻辑复制到复制构造函数中。然后完成复制构造函数,从Matrix中复制double的值。

对于operator+,如果你不知道你应该为不同大小的矩阵return设置什么,那么我建议throw设置一个例外。

同样,即使你当前的代码还没有使用这个,你应该添加一个复制赋值operator=来完成规则3(你已经有了复制构造函数和析构函数)。

试试这个:

#ifndef MATRIX_HEADER
#define MATRIX_HEADER
typedef unsigned int u_int;
class Matrix
{
double **mtrx;
//or: double *mtrx;
u_int x, y;
public:
Matrix(u_int a, u_int b);
Matrix(const Matrix &);
~Matrix();
double det();
Matrix& operator=(const Matrix &);
Matrix operator+(const Matrix &) const;
Matrix operator-(const Matrix &) const;                           
Matrix operator*(const Matrix &) const;
friend Matrix operator*(const Matrix &, const double &);
Matrix operator/(const Matrix &) const;
double* operator[](const u_int idx) const {
return mtrx[idx];
//or: return &mtrx[idx*x];
}
bool IsEqualSize(const Matrix &) const;
u_int GetX() const { return x; }
u_int GetY() const { return y; }
};
#endif
#include "Matrix.hpp"
#include <utility>
#include <stdexcept>
Matrix::Matrix(u_int a, u_int b)
: x(a), y(b)
{
mtrx = new double*[x];
for (u_int i = 0; i < x; ++i) {
mtrx[i] = new double[y];
}
// or: mtrx = new double[x*y];
}
Matrix::Matrix(const Matrix &ref)
: x(ref.x), y(ref.y)
{
mtrx = new double*[x];
for (u_int i = 0; i < x; ++i) {
mtrx[i] = new double[y];
for (u_int j = 0; j < y; ++j) {
mtrx[i][j] = ref.mtrx[i][j];
}
}
/* or:
u_int size = x*y;
mtrx = new double[size];
for (u_int i = 0; i < size; ++i) {
mtrx[i] = ref.mtrx[i];
}
*/
}
Matrix::~Matrix()
{
// this loop is not needed for a 1D array...
for (u_int i = 0; i < x; ++i) {
delete[] mtrx[i];
}
delete[] mtrx;
}
bool Matrix::IsEqualSize(const Matrix &a) const
{
return (a.GetX() == x) && (a.GetY() == y);
}
Matrix& Matrix::operator=(const Matrix &a)
{
if (&a != this)
{
Matrix tmp(a);
std::swap(mtrx, tmp.mtrx);
}
return *this;
}
Matrix Matrix::operator+(const Matrix &a) const
{
if (!IsEqualSize(a))
throw std::logic_error("Cannot add matrices of different sizes");
Matrix matrix(x, y);
for (u_int i = 0; i < x; ++i) {
for (u_int j = 0; j < y; ++j)
matrix.mtrx[i][j] = mtrx[i][j] + a.mtrx[i][j];
}
/* or:
u_int size = x*y;
for (u_int i = 0; i < size; ++i) {
matrix.mtrx[i] = mtrx[i] + a.mtrx[i];
}
*/
return matrix;
}
...
#include <stdio.h>
#include "Matrix.hpp"
int main()
{
Matrix a(2, 5);
Matrix b(2, 5);
for (u_int i = 0; i < a.GetX(); ++i)
{
for (u_int j = 0; j < a.GetY(); ++j)
{
a[i][j] = i + j;
}
}
for (u_int i = 0; i < b.GetX(); ++i)
{
for (u_int j = 0; j < b.GetY(); ++j)
{
b[i][j] = i + j;
}
}
Matrix c = a + b;
return 0;
}

最新更新