如何使用重载运算符解决此内存泄漏?

时间:2019-04-19 17:19:32

标签: c++ matrix memory-management memory-leaks

我从C++ Super-FAQ的“操作符重载”部分扩展了Matrix类。我通过Valgrind运行了程序:

==6208== 48 (16 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 6
==6208==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6208==    by 0x108E98: Matrix::operator*(Matrix&) (in /home/l/a.out)
==6208==    by 0x1090BA: main (in /home/l/a.out)
==6208== 
==6208== 48 (16 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6
==6208==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6208==    by 0x108FC2: Matrix::transpose() const (in /home/l/a.out)
==6208==    by 0x108EC2: Matrix::operator*(Matrix&) (in /home/l/a.out)
==6208==    by 0x1090BA: main (in /home/l/a.out)

我可以看到问题出在operator*中。我对该操作符的实现如下:

Matrix &Matrix::operator*(Matrix &m) {
    auto result = new Matrix(rows_, m.cols_);
    auto &mTranspose = m.transpose();
    for (unsigned i = 0; i < rows_; ++i) {
        for (unsigned j = 0; j < m.cols_; ++j) {
            result->data_[i][j] = std::inner_product(data_[i], data_[i] + cols_, mTranspose.data_[j], 0);
        }
    }
    return *result;
}

我使用以下示例main()中所示的模式给操作员打电话:

int main() {
    Matrix m(2,2);
    Matrix n(2,2);

    auto &a = m * n; // pattern A
    auto * b = &(m*n); // pattern B

我在运算符中的堆上分配对象的原因是,我需要Matrix乘法的结果才能在乘法完成后保持不变;在程序的其他地方,我使用了一个循环,需要跟踪以前的Matrix乘法。

如何解决此内存泄漏?

1 个答案:

答案 0 :(得分:4)

只需声明一个局部变量,然后将其返回即可。

Matrix result(rows_, m.cols_);
// ....
return result;

使用它时,只需像对实数相乘一样使用它。

auto a = m * n;    // Not a reference
auto b = m * n;    // Not a pointer

根据m.transpose()返回的内容,转置可能需要为auto mTranspose = m.transpose();(即不是引用)。