Как правильно вызывать деструктор, когда у вас есть двумерный массив (в C ++)?

0

Это мой конструктор:

Matrix::Matrix(int rows, int columns)
{
  elements = new int*[rows];
  for (int x = 0; x < rows; x++)
  {
    elements[x] = new int[columns];
  }
}

И это мой деструктор:

Matrix::~Matrix()
{
    delete elements;
}

Я изменил деструктор, чтобы сказать "delete [] elements", "delete * elements", "delete elements *", и всевозможные комбинации и каждая комбинация замерзает программу. Я также попытался "удалить это", но это также зависнет. Я бы попробовал "free()", но я слышал эту плохую практику программирования, и на самом деле она не освобождает память.

Любая помощь приветствуется.

  • 4
    Использование зубчатого массива не лучше, чем использование 2D std::vector . Если это то, что вы хотите, используйте вектор и забудьте об этой ерунде. Если нет, используйте одномерный массив (такой как std::unique_ptr<int[]> или std::vector<int> ), обернутый в класс Matrix а также забудьте об этой ерунде.
  • 0
    Попробуйте сохранить размеры Matrix и затем использовать for (int x=0; x<rows; x++){delete[] elements[x];} delete[] elements;
Показать ещё 6 комментариев
Теги:
arrays
multidimensional-array
destructor

2 ответа

1
Лучший ответ

Это не дает мне утечек с valgrind --leak-check=yes

Редактировать: добавлена копия-конструктор, позволяющая Matrix myMat2 = myMat; стиль звонков. Вероятно, к этому моменту вам следует искать функцию стиля swap и оператор копирования. И так далее, и так далее...

#include <iostream>

class Matrix
{
    int** elements;
    int rows_;

    public:
    Matrix(int, int);
    ~Matrix();
    Matrix(const Matrix&);
};

Matrix::Matrix(int rows, int columns)
{
    std::cout<< "Matrix constructor called" << std::endl;
    rows_ = rows;
    elements = new int*[rows];
    for (int x=0; x<rows; x++)
    {
        elements[x] = new int[columns];
    }
}

Matrix::~Matrix()
{
    for (int x=0; x<rows_; x++)
    {
        delete[] elements[x];
    }
    delete[] elements;
    std::cout<< "Matrix destructor finished" << std::endl;
}

Matrix::Matrix(const Matrix &rhs)
{
    std::cout<< "Called copy-constructor" << std::endl;
    rows_ = rhs.rows_;
    columns_ = rhs.columns_;
    elements = new int*[rows_];
    for (int x=0; x<rows_; x++)
    {
        elements[x] = new int[columns_];
        *(elements[x]) = *(rhs.elements[x]);
    }
}

int main()
{
    Matrix myMat(5, 3);
    Matrix myMat2 = myMat;
    return 0;
}

Выход Valgrind:

user:~/C++Examples$ valgrind --leak-check=yes ./DestructorTest
==9268== Memcheck, a memory error detector
==9268== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9268== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==9268== Command: ./DestructorTest
==9268== 
Matrix constructor called
Called copy-constructor
Matrix destructor finished
Matrix destructor finished
==9268== 
==9268== HEAP SUMMARY:
==9268==     in use at exit: 0 bytes in 0 blocks
==9268==   total heap usage: 12 allocs, 12 frees, 200 bytes allocated
==9268== 
==9268== All heap blocks were freed -- no leaks are possible
==9268== 
==9268== For counts of detected and suppressed errors, rerun with: -v
==9268== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
  • 1
    Пока вы не сделаете Matrix myMat2 = myMat; :) (В этом случае не столько утечка, сколько двойное освобождение)
  • 0
    Вопрос не в том, чтобы создавать операторы копирования-копирования, хотя ...
Показать ещё 2 комментария
0

Вы должны следовать совету @chris. Но если вы хотите знать, как это сделать в любом случае:

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

delete[] elements;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню