创建矩阵类:添加时出错

发布于 2024-11-19 03:58:42 字数 5115 浏览 3 评论 0原文

我正在尝试使用 C++ 创建一个 Matrix 类。到目前为止,我已经完成了以下工作:

  • 创建矩阵
  • 删除矩阵
  • 获取和设置矩阵内部的值

现在,我正在努力覆盖所有运算符(即 +、-、*、/)并返回矩阵。我在这方面遇到了很多问题,所以我想知道是否有人可以提供帮助?

而且我在将矩阵复制到新矩阵中时也遇到问题,因此任何有关该代码的帮助将不胜感激。

注意:我有 Python 背景,并且了解一点 C++。我决定,虽然用 Python 创建很多非常酷的游戏和 OOP 东西很棒而且很酷,但我应该学习 C++,以便在我长大后找到一份工作。

这是我的代码,我有一个包含原型和类定义的标头,然后是主标头。

matrix.h

#ifndef MATRIX_H
#define MATRIX_H

/*

// These are all of the error codes
// Upon changing errorcode, Matrix should reset to null/void

*/

#define ERROR_ROW_NP 1          // Row Number cannot be non-positive
#define ERROR_COLUMN_NP 2       // Column Number cannot be non-positive
#define ERROR_ROW_I 3           // Row Index Error
#define ERROR_COLUMN_I 4        // Column Index Error
#define ERROR_RC_MISMATCH 5     // # of Rows and Columns do not match

class Matrix {
    int row;
    int column;
    int elements;

    int *RC;

  public:
    int ERRORCODE;

    Matrix (void);                  // DONE
    Matrix (int, int);              // DONE
    ~Matrix (void);                 // DONE

    void Copy (Matrix);

    int get_value (int, int);       // DONE
    void set_value (int, int, int); // DONE

    int rc_match (Matrix);          // DONE

    Matrix operator+ (Matrix);
    Matrix operator- (Matrix);

    Matrix operator* (Matrix);

    Matrix operator* (int);
    Matrix operator/ (int);

};

#endif

matrix.cpp

#include "matrix.h"

Matrix::Matrix (void) {
    ERRORCODE = 0;

    row = 1;
    column = 1;
    elements = row * column;

    RC = new int[elements];

    for (int i=0; i< elements; i++) {
        RC[i] = 0;
    }
}

Matrix::Matrix (int r, int c) {
    ERRORCODE = 0;

    row = r;
    column = c;
    elements = row * column;

    RC = new int[elements];

    for (int i=0; i< elements; i++) {
        RC[i] = 0;
    }
}

Matrix::~Matrix (void) {
    delete[] RC;
}


// Copy will copy all of the contents of the toCopy
// matrix into itself; also resets it's own rows/columns
void Matrix::Copy (Matrix toCopy) {
    row = toCopy.row;
    column = toCopy.column;
    elements = toCopy.elements;

    RC = new int[elements];

    for (int i=0; i<elements; i++) {
        RC[i] = toCopy.RC[i];
    }
}

int Matrix::get_value (int r, int c) {
    return RC[(column*r)+c];
}

void Matrix::set_value (int r, int c, int value) {
    RC[(column*r)+c] = value;
}


int Matrix::rc_match (Matrix a) {
    if (
        (row == a.row)
        &&
        (column == a.column)
        ) {
            return (1);
    }
    else {
        return (0);
    }
}


Matrix Matrix::operator+ (Matrix a) {
    if (rc_match(a)) {
        Matrix OUT(row, column);
        int z;
        for (int i=0; i < row; i++) {
            for (int j=0; j < column; j++) {
                z = OUT.get_value(i, j) + a.get_value(i, j);
                OUT.set_value(i, j, z);
            }
        }
        return OUT;
    }
    else {
        Matrix OUT(1, 1);
        OUT.ERRORCODE = ERROR_RC_MISMATCH;
        return OUT;
    }
}

main.cpp

#include <iostream>
#include "matrix.h"

int main(void) {

    Matrix a(2, 2);
    a.set_value(0, 0, 3);
    a.set_value(0, 1, 2);

    Matrix b(2, 2);
    b.set_value(0, 0, 1);
    b.set_value(0, 1, 1);
    b.set_value(1, 0, 3);
    b.set_value(1, 1, 3);

    printf("%d %d\n", a.get_value(0, 0), a.get_value(0, 1));
    printf("%d %d\n", a.get_value(1, 0), a.get_value(1, 1));
    printf("\n");

    printf("%d %d\n", b.get_value(0, 0), b.get_value(0, 1));
    printf("%d %d\n", b.get_value(1, 0), b.get_value(1, 1));

    char t[1];
    printf("Press 'Enter' to continue...");
    std::cin.getline(t, 1);
    printf("\n");

    Matrix c;
    c.Copy(a+b);

    printf("%d %d\n", c.get_value(0, 0), c.get_value(0, 1));
    printf("%d %d\n", c.get_value(1, 0), c.get_value(1, 1));

    printf("Press 'Enter' to continue...");
    std::cin.getline(t, 1);
    printf("\n");

    return (0);
}

我在编译和运行时遇到的错误是这样的:

Debug assertion failed! ...
Expression: _BLOCK_TYPE_IS_VALID(pHead ->nBlockUse)

按“Enter”后弹出

另外,这是我第一次发帖,如果我做错了什么,请告诉我:]

EDIT2: 我让它工作了! 谢谢@templatetypedef!

这是我使用的附加代码: (我发现我的add函数也错了) matrix.cpp

Matrix::Matrix(const Matrix& toCopy) {
    row = toCopy.row;
    column = toCopy.column;
    elements = toCopy.elements;

    RC = new int[elements];

    for (int i=0; i<elements; i++) {
        RC[i] = toCopy.RC[i];
    }
}

Matrix Matrix::operator+ (Matrix a) {
    if (rc_match(a)) {
        Matrix OUT(row, column);
        int z;
        for (int i=0; i < row; i++) {
            for (int j=0; j < column; j++) {
                z = get_value(i, j) + a.get_value(i, j);
                OUT.set_value(i, j, z);
            }
        }
        return OUT;
    }
    else {
        Matrix OUT(1, 1);
        OUT.ERRORCODE = ERROR_RC_MISMATCH;
        return OUT;
    }
}

所以现在我将研究赋值运算符

I am trying to create a Matrix class using c++. So far, I have the following accomplished:

  • Creating the Matrix
  • Deleting the Matrix
  • Getting and setting values inside of the matrix

Right now, I am working on overriding all of the operators (ie., +, -, *, /) and returning matrices. I'm having a lot of issues on this, so I was wondering if anyone could help?

And I'm also having issues with copying the matrix into a new one, so any help with that code would be appreciated.

Note: I am coming from a Python background, and I know a bit of c++. I decided that while yes, creating a lot of really cool games and OOP stuff in Python is awesome and cool, I should learn c++ in order to be getting a job when I'm older.

Here's my code, I have a header containing the prototype and the class definitions, then the main one.

matrix.h

#ifndef MATRIX_H
#define MATRIX_H

/*

// These are all of the error codes
// Upon changing errorcode, Matrix should reset to null/void

*/

#define ERROR_ROW_NP 1          // Row Number cannot be non-positive
#define ERROR_COLUMN_NP 2       // Column Number cannot be non-positive
#define ERROR_ROW_I 3           // Row Index Error
#define ERROR_COLUMN_I 4        // Column Index Error
#define ERROR_RC_MISMATCH 5     // # of Rows and Columns do not match

class Matrix {
    int row;
    int column;
    int elements;

    int *RC;

  public:
    int ERRORCODE;

    Matrix (void);                  // DONE
    Matrix (int, int);              // DONE
    ~Matrix (void);                 // DONE

    void Copy (Matrix);

    int get_value (int, int);       // DONE
    void set_value (int, int, int); // DONE

    int rc_match (Matrix);          // DONE

    Matrix operator+ (Matrix);
    Matrix operator- (Matrix);

    Matrix operator* (Matrix);

    Matrix operator* (int);
    Matrix operator/ (int);

};

#endif

matrix.cpp

#include "matrix.h"

Matrix::Matrix (void) {
    ERRORCODE = 0;

    row = 1;
    column = 1;
    elements = row * column;

    RC = new int[elements];

    for (int i=0; i< elements; i++) {
        RC[i] = 0;
    }
}

Matrix::Matrix (int r, int c) {
    ERRORCODE = 0;

    row = r;
    column = c;
    elements = row * column;

    RC = new int[elements];

    for (int i=0; i< elements; i++) {
        RC[i] = 0;
    }
}

Matrix::~Matrix (void) {
    delete[] RC;
}


// Copy will copy all of the contents of the toCopy
// matrix into itself; also resets it's own rows/columns
void Matrix::Copy (Matrix toCopy) {
    row = toCopy.row;
    column = toCopy.column;
    elements = toCopy.elements;

    RC = new int[elements];

    for (int i=0; i<elements; i++) {
        RC[i] = toCopy.RC[i];
    }
}

int Matrix::get_value (int r, int c) {
    return RC[(column*r)+c];
}

void Matrix::set_value (int r, int c, int value) {
    RC[(column*r)+c] = value;
}


int Matrix::rc_match (Matrix a) {
    if (
        (row == a.row)
        &&
        (column == a.column)
        ) {
            return (1);
    }
    else {
        return (0);
    }
}


Matrix Matrix::operator+ (Matrix a) {
    if (rc_match(a)) {
        Matrix OUT(row, column);
        int z;
        for (int i=0; i < row; i++) {
            for (int j=0; j < column; j++) {
                z = OUT.get_value(i, j) + a.get_value(i, j);
                OUT.set_value(i, j, z);
            }
        }
        return OUT;
    }
    else {
        Matrix OUT(1, 1);
        OUT.ERRORCODE = ERROR_RC_MISMATCH;
        return OUT;
    }
}

main.cpp

#include <iostream>
#include "matrix.h"

int main(void) {

    Matrix a(2, 2);
    a.set_value(0, 0, 3);
    a.set_value(0, 1, 2);

    Matrix b(2, 2);
    b.set_value(0, 0, 1);
    b.set_value(0, 1, 1);
    b.set_value(1, 0, 3);
    b.set_value(1, 1, 3);

    printf("%d %d\n", a.get_value(0, 0), a.get_value(0, 1));
    printf("%d %d\n", a.get_value(1, 0), a.get_value(1, 1));
    printf("\n");

    printf("%d %d\n", b.get_value(0, 0), b.get_value(0, 1));
    printf("%d %d\n", b.get_value(1, 0), b.get_value(1, 1));

    char t[1];
    printf("Press 'Enter' to continue...");
    std::cin.getline(t, 1);
    printf("\n");

    Matrix c;
    c.Copy(a+b);

    printf("%d %d\n", c.get_value(0, 0), c.get_value(0, 1));
    printf("%d %d\n", c.get_value(1, 0), c.get_value(1, 1));

    printf("Press 'Enter' to continue...");
    std::cin.getline(t, 1);
    printf("\n");

    return (0);
}

The error I am getting upon compiling and running is this:

Debug assertion failed! ...
Expression: _BLOCK_TYPE_IS_VALID(pHead ->nBlockUse)

That pops up after hitting 'Enter'

Also, this is my first time posting, if I did anything wrong, let me know please :]

EDIT2:
I got it to work!
Thank you @templatetypedef!

Here's the additional code I used:
(I found out that my add function was wrong too)
matrix.cpp

Matrix::Matrix(const Matrix& toCopy) {
    row = toCopy.row;
    column = toCopy.column;
    elements = toCopy.elements;

    RC = new int[elements];

    for (int i=0; i<elements; i++) {
        RC[i] = toCopy.RC[i];
    }
}

Matrix Matrix::operator+ (Matrix a) {
    if (rc_match(a)) {
        Matrix OUT(row, column);
        int z;
        for (int i=0; i < row; i++) {
            for (int j=0; j < column; j++) {
                z = get_value(i, j) + a.get_value(i, j);
                OUT.set_value(i, j, z);
            }
        }
        return OUT;
    }
    else {
        Matrix OUT(1, 1);
        OUT.ERRORCODE = ERROR_RC_MISMATCH;
        return OUT;
    }
}

So for now I shall look into the assignment operator

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无人问我粥可暖 2024-11-26 03:58:42

我认为这里的问题是您的 Matrix 类有析构函数,但没有复制构造函数或复制赋值运算符。这意味着在运算符 + 的代码中,当您返回矩阵时,您将获得矩阵的浅副本而不是深层副本。这意味着浅拷贝将共享一个指向与运算符 + 中本地声明的矩阵相同元素的指针。当这个局部变量超出范围时,它的析构函数将触发,回收该矩阵的内存。因此,返回的矩阵将具有指向已释放内存的指针,从而导致未定义的行为。

要解决此问题,请尝试为您的 Matrix 类实现复制构造函数和赋值运算符。作为一个无耻的自我插件,我曾经写过一个关于如何做到这一点的指南,这在这里可能有用。

希望这有帮助!

I believe that the problem here is that your Matrix class has a destructor, but not a copy constructor or copy assignment operator. This means that in your code for operator +, when you return a matrix, you'll get a shallow copy of the matrix rather than a deep copy. This means that the shallow copy will share a pointer to the same elements as the locally-declared matrix in operator +. When this local variable goes out of scope, its destructor will fire, reclaiming the memory for that matrix. Consequently, the returned matrix will have a pointer to deallocated memory, resulting in undefined behavior.

To fix this, try implementing a copy constructor and assignment operator for your Matrix class. As a shameless self-plug, I once wrote a guide on how to do this, which might be useful here.

Hope this helps!

千鲤 2024-11-26 03:58:42

@templatetypedef 和@Kerrek 已经确定了您的问题。

通过使用 std::vector 来保存矩阵元素而不是手动管理内存,可以轻松解决此问题。复制构造函数和赋值运算符将由编译器自动实现,就 std::vector 的复制构造函数和赋值运算符而言,您可以摆脱析构函数代码。作为奖励,您可以删除 Copy 函数及其内存泄漏。

@templatetypedef and @Kerrek have identified your problem.

It can be solved trivially by using std::vector to hold your matrix elements instead of manually managing memory. Copy constructor and assignment operator will be implemented automatically by the compiler, in terms of std::vector's copy constructor and assignment operator, and you can get rid of your destructor code. As a bonus, you could then remove the Copy function along with its memory leak.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文