Как я могу исправить эту утечку памяти с перегруженным оператором? - PullRequest
0 голосов
/ 19 апреля 2019

Я расширяю класс Matrix из раздела "Перегрузка оператора" в C ++ Super-FAQ *1003*.Я прогнал мою программу через 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 Ответ

4 голосов
/ 19 апреля 2019

Просто объявите локальную переменную и верните ее.

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(); (т. е. не ссылка).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...