1

我是 C++ 的初学者程序员。最近,我开始使用 C++ 进行图像处理。我正在尝试定义和使用以下功能:

Matrix MVE(Matrix R, double tolerance)
{
    int n = R.Y();
    Matrix P(n,4);
    for (int i = 0; i < n; ++i)
    {
            P[i][0] = R[i][0];
            P[i][1] = R[i][1];
            P[i][2] = R[i][2];
            P[i][3] = 1.0;
    }
    Matrix *Q = P.T();
            double err = 1.0;
    MatVectorCol u(n);                      
    u.Set(1.0 / n);
    MatVectorCol Mv(n);                 

    while (err > tolerance)                         
    {
            Matrix uM(n, n);
            uM.SetDiagonal(u);
            Matrix *X = *Q * uM;
            Matrix *X1 = *X * P; 
            Matrix invX(4, 4);
            invX = *X1->Inverse();
     delete X;  // Error here!
            delete X1;
    }

    return invX;
}

但是当我程序执行“删除X”行时出现此错误;:

Windows 在 plappd.exe 中触发了断点。

这可能是由于堆损坏,这表明 plappd.exe 或其已加载的任何 DLL 中存在错误。

这也可能是由于用户在 plappd.exe 获得焦点时按 F12。

Matrix 类的构造函数和操作定义如下:

Matrix::Matrix(int _y, int _x) 
{ 
    x = _x; 
    y = _y; 
    M = new double [x * y]; 
    buff = new double [x]; 
    memset0_64(M, sizeof(double) * (x * y));
}

Matrix *Matrix::Transpose()
{
    Matrix *b = new Matrix(x, y);
    for (int i = 0; i < x; ++i)
    {
            double *b_line_i = (*b)[i];
            for (int j = 0; j < y; ++j)
                    b_line_i[j] = (*this)[j][i];
    }
    return b;
}

Matrix *Matrix::operator * (const Matrix &m)
{
    if (x == m.y)
    {
            Matrix *b = new Matrix(y, m.x);
            for (int i = 0; i < y; ++i)
            {
                    double *b_line_i = (*b)[i];
                    double *line_i = (*this)[i];
                    for (int j = 0; j < m.x; ++j)
                            for (int k = 0; k < x; ++k)
                                    b_line_i[j] += line_i[k] * m(k, j);
            }
            return b;
    }
    else
            return 0;
}       

当然,代码有问题,但我不知道它在哪里以及如何解决它。

提前致谢。

4

1 回答 1

2

您的代码的错误之处在于您过度使用/滥用 operator new 和动态内存分配。除非必须,否则不要动态分配内存——这很容易出错,如果你是“初学者”,你绝对应该避免这样做。(除非您使用另一种语言的动态分配内存并知道您在做什么)。

new而不是用, usestd::vector<double>或类似的容器分配双打。这样你就不必编写析构函数了。

如果你的类动态分配内存,它必须有析构函数。C++ 没有垃圾收集,所以没有人会清理你的烂摊子并为你释放资源。

如果你的类有析构函数,它应该遵守三规则。您应该定义复制构造函数和赋值运算符。不这样做将导致内存泄漏、未定义的行为和崩溃。

不要从运算符内部返回原始指针。不要从运算符返回动态分配的对象(如果必须返回动态分配的对象,请创建单独的函数)。如果您必须返回动态分配的对象,请使用智能指针,因此它们的销毁将是自动的(std::shared_ptrboost::shared_ptr应该工作)。

传统上,operator*应该按值返回对象。它应该如下所示:

Matrix Matrix::operator* (const Matrix &arg1, const Matrix &arg2){...}|
于 2013-09-24T14:09:08.307 回答