如何使用重载运算符修复此内存泄漏?

问题描述 投票:0回答:1

我一直在扩展Matrix类来自C++ Super-FAQ的“运算符重载”部分。我通过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倍数。

如何修复此内存泄漏?

c++ matrix memory-management memory-leaks
1个回答
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();(即,不是参考)。

© www.soinside.com 2019 - 2024. All rights reserved.