Where to put delete?
In your case, you must provide a special function releaseMatrix(ncount, matrix); in which will be what Denis Rakitin wrote
And in an amicable way, to the Matrix type wrapper destructor, which will own the pointers. When a Matrix object dies (exit from a method, the death of the owner class whose member was a Matrix object or an exception in general), then the memory is also freed. RAII
template<typename T> class Matrix { public: typedef T value_type; typedef size_t dim_size; Matrix(dim_size n, dim_size m) : _n(n), _m(m), _buffer(new T[ n * m ]) { } ~Matrix() { delete [] _buffer; } dim_size getRowsCount() const { return _n; } dim_size getColsCount() const { return _m; } T& at(dim_size row, dim_size col) { return _buffer[ row * _m + col ]; } private: const int _n, _m; T *_buffer; Matrix(const Matrix<T>& other) =delete; Matrix(Matrix<T>&& other) =delete; Matrix& operator=(const Matrix<T>& other) =delete; Matrix& operator=(Matrix<T>&& other) =delete; };
Or just use a smart pointer with custom deleter:
template<class T> using MatrixPtr = std::unique_ptr<T**,std::function<void(T***)>; template<class T> MatrixPtr& createMatrix(int ncount, int mcount) { T **matrix = new T*[ncount]; for (int i = 0; i < ncount; ++i) { matrix[i] = new T[mcount]; // допустим, что мы не боимся std::bad_alloc std::fill(matrix[i], matrix[i] + mcount, T()); } return MatrixPtr(matrix, [ncount](T ***matrix) { for (int i = 0; i < ncount; ++i) { delete[] *matrix[i]; } delete[] *matrix; }); }