我从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
乘法。
如何解决此内存泄漏?
答案 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();
(即不是引用)。