In visual studio _CrtDumpMemoryLeaks() has detected memory leaks! But I could not find how it is happening. Please tell me what is wrong with the following code.?
// Declaration
template <class T> class cMatrix {
private:
std::vector<std::vector<T> > mat;
unsigned rows;
unsigned cols;
public:
cMatrix(unsigned _rows, unsigned _cols, const T& _initial);
cMatrix(const cMatrix<T>& rhs);
virtual ~cMatrix();
}
//Constructor
template<class T>
cMatrix<T>::cMatrix(unsigned _rows, unsigned _cols, const T& _initial) {
mat.resize(_rows);
for (unsigned i=0; i<mat.size(); i++) {
mat[i].resize(_cols, _initial);
}
rows = _rows;
cols = _cols;
}
//VirtualDestructor
template<class T>
cMatrix<T>::~cMatrix() {}
mat1 and mat4 can be destroyed after CrtDumpMemoryLeaks() call, move declaration of variable to own block.
int main()
{
{
cMatrix<double> mat1(2, 3, 23.0), mat4(2, 3, 15.0);
}
CrtDumpMemoryLeaks();
return 0;
}
Problem is that _CrtDumpMemoryLeaks(); is called in the same scope as vector is, so object does not get destroyed when it is called.
This won't show any memory leaks:
int main()
{
{
cMatrix<double> mat1(2, 3, 23.0), mat4(2, 3, 15.0);
}
_CrtDumpMemoryLeaks();
}
By the way, more efficient way to define cMatrix would be
// Declaration
template <class T> class cMatrix {
private:
std::vector<std::vector<T> > mat;
unsigned rows;
unsigned cols;
public:
cMatrix(unsigned _rows, unsigned _cols, const T& _initial);
virtual ~cMatrix();
};
//Constructor
template<class T>
cMatrix<T>::cMatrix(unsigned _rows, unsigned _cols, const T& _initial)
: mat(_rows,std::vector<T>(_cols,_initial))
, rows(_rows)
, cols(_cols)
{
}
//VirtualDestructor
template<class T>
cMatrix<T>::~cMatrix() {}
You've gotten some advice giving one possible way to deal with the problem you've seen. At least IMO, there's a somewhat better way though. Instead of mixing the diagnostic code with the other code, then adding braces to introduce a scope that's irrelevant to the real code, I'd separate the leak-dumping code even more completely, by putting it into a separate class:
struct leak_dumper {
~leak_dumper() { _CrtDumpMemoryLeaks(); }
} dump_leaks_at_exit;
This creates a global instance of the object, so you can simply add these three lines of code to the same file that contains your main (or WinMain) and it'll do the leak-dumping after main exits (with no other modification of your existing code).
As far as how to define a 2D matrix goes: a vector of vectors generally makes sense only if different rows of the matrix might contain different numbers of columns. If you want a rectangular matrix, you're generally better off with a single vector, and converting 2D coordinates to one dimension in an overloaded operator.
template <class T>
class matrix2D {
std::vector<T> data;
int columns;
public:
T &operator()(int x, int y) {
return data[y * columns + x];
}
matrix2D(int x, int y) : data(x*y), columns(x) {}
};
This reduces the total memory you use and, perhaps more importantly, keeps the data contiguous instead of allocating the data for each row separately.
Related
The following code contains a simple example of a Matrix class, with double indexing [][] enabled using a 'proxy' Row class.
#include <valarray>
#include <iostream>
template <typename T>
class Matrix {
private:
// Data members
int nRows_;
int nColumns_;
std::valarray<T> data_;
public:
// Constructor
Matrix(const int nRows,
const int nColumns)
: nRows_{nRows},
nColumns_{nColumns},
data_{std::valarray<T>(nRows*nColumns)} {}
// Row friend class to enable double indexing
class Row {
friend class Matrix;
private:
// Constructor
Row(Matrix& parent,
int row)
: parent_{parent},
row_{row} {}
// Data members
Matrix& parent_;
int row_;
public:
// Index columns
T& operator[](int column) {
int nColumns{parent_.nColumns_};
int element{row_*nColumns + column};
return parent_.data_[element];
}
};
// Index rows
Row operator[](int row) {
return Row(*this, row);
}
};
However, this doesn't allow double indexing of a const Matrix. For example, the below code fails to compile when the last line is included.
int main() {
Matrix<int> a{3,3};
const Matrix<int> b{3,3};
std::cout << a[1][2];
std::cout << b[1][2];
}
So the question is, how can I modify my Matrix class to allow for double indexing of const Matrix objects?
Since b is a const Matrix, you need to add const versions of your indexing operator.
Row operator[](int row) const { ... }
This will require additional changes to the Row class (or a second proxy class) to handle the const Matrix & and const overload of operator[].
I think I'm lacking a logical understanding of why things need/need not be const
It depends if you can modify argument or not. in general operator[] should not change object (unless it does, but then...ugh), it should return reference to object's resource. Tada! Your implementation doesn't allow that, because valarray is const then. You cant assign const matrix reference to
Matrix& parent_;
And as result
Row(const Matrix& parent, int row)
Why store Matrix itself... I'd stored reference of valarray.
Actually I would ditch container and create own transparent array in heap. that way Row would have a reference to part of array and length of row, nearly zero of overhead.
I am implementing a Matrix class in C++ and I want to be able to initialize it with an intializer list like so:
Matrix<double, 2, 3> m({{1,2,1},
{0,1,1}});
In the class I have implemented the constructor like this:
template<typename Ty, unsigned int rows, unsigned int cols>
class Matrix
{
std::array<std::array<Ty, cols>, rows> data;
public:
Matrix(const std::initializer_list<std::initializer_list<Ty>>& list)
{
int i = 0;
for (auto& list_row : list)
{
int j = 0;
for (auto& list_value : list_row)
{
data[i][j++] = list_value;
}
i++;
}
}
}
The code work but I have a couple of questions. Is it possible to make it safe, so it only takes initializer lists of a certain size(the size of the matrix) and secondly can I make the code more concise - I had imagined something like this:
Matrix(const std::initializer_list<std::initializer_list<Ty>>& list)
: data(list)
{ }
And it doesn't work but any better way to do it would be appreciated.
There's a pretty easy way to make it safe:
template<typename Ty, unsigned int rows, unsigned int cols>
class Matrix
{
std::array<std::array<Ty, cols>, rows> data;
public:
Matrix(std::array<std::array<Ty, cols>, rows> const& in)
: data(in)
{ }
};
This lets you almost use the syntax you want - you just need one extra set of {}s.
There's no way to statically enforce the size of a std::initializer_list - you'd have to assert or throw to prevent me from passing in a bunch of extra values and causing you to perform out-of-range writes.
I'm trying to perform a strided access to a submatrix with a single index. I need this for a library I'm working on which uses expression templates. I have worked out the following class, where the access is performed by the overloaded operator[], see below:
template <class A, class Type>
class SubMatrixExpr
{
private:
int Rows_; // Rows of the SubMatrix
int Columns_; // Columns of the SubMatrix
int Rows_up_; // Rows of the original Matrix
int Columns_up_; // Columns of the original Matrix
int a_, c_; // Starting indices of the SubMatrix as evaluated in the original Matrix
int rowstep_, columnstep_; // Stride along rows and columns for the original matrix
A M_;
public:
SubMatrixExpr(A &M, int Rows_up, int Columns_up, int Rows, int Columns, int a, int rowstep, int c, int columnstep) :
a_(a), c_(c), M_(M),
Rows_(Rows),
Columns_(Columns),
Rows_up_(Rows_up), Columns_up_(Columns_up),
rowstep_(rowstep), columnstep_(columnstep) { }
inline const Type& operator[](const int i) const
{
const int LocalRow = i/Columns_;
const int LocalColumn = i%Columns_;
const int GlobalRow = a_+rowstep_*LocalRow;
const int GlobalColumn = c_+columnstep_*LocalColumn;
return M_[IDX2R(GlobalRow,GlobalColumn,Columns_up_)];
}
inline Type& operator[](const int i)
{
// Similar to above
}
};
where
#define IDX2R(i,j,N) (((i)*(N))+(j))
The overloaded operator[] works correctly, but is computationally very expensive.
Is there any way to better implement the overloaded operator[]?
Thanks a lot in advance.
The only way you may got speedup is if you now the size of the matrices and sub-matrices at compile time. Then using template / constexpr may speedup things. For example if the size is known to be a power of 2 at compile time, the compiler will be able to replace division by shift.
Annoyance over C++'s requirement to pass a dimension in a 2-d array got me working on a templated Matrix class. I've been coding in C# for a bit, so I'm sure I'm a little rusty here.
Issue is, I get a heap exception as soon as I hit the destructor, which is trying to delete the 2-d array.
Any help gratefully accepted!
template <typename T>
class Matrix {
public:
Matrix(int m, int n) : nRows(m), nCols(n) {
pMatrix = new T * [nRows];
for (int i = 0; i < nCols; i++) {
pMatrix[i] = new T[nCols];
}
}
~Matrix() {
if (pMatrix != NULL) {
for (int i = 0; i < nRows; i++) { delete[] pMatrix[i]; }
delete[] pMatrix;
}
}
T ** GetMatrix() const { return pMatrix; }
T * Row(int i) const { return pMatrix[i]; }
inline T Cell(int row, int col) const { return pMatrix[row][col]; }
inline int GetNRows() const { return nRows; }
inline int GetNCols() const { return nCols; }
private:
int nRows, nCols;
T ** pMatrix;
};
This is the bug:
for (int i = 0; i < nCols; i++) {
pMatrix[i] = new T[nCols];
}
The loop should be until nRows, not nCols.
Other than that, let me tell you about something I did when I got tired of allocating 2-d arrays. I had to do a 3-d array. I used a map, that mapped from a coordinate - a struct holding x, y, z to the type I wanted.
I worked fast, and no need to allocate or deallocate. Assigning to a coordinate was simply done by
mymap[Coord(x, y, z)] = whatever...
Of course I needed to define the Coord struct and overload the < operator, but I found that way more comvenient than trying to allocate and deallocate a 3-d array.
Of course you will need to check if this scheme is fast enough for you. I used it to draw cells within a big cube using OpenGL and had no complaints at all.
Concerning the bug, #CodeChords_man explained it right. I have notes on implementation. I recommend to look through this wonderful FAQ post.
You should not use dynamic memory allocation unless you are 100% sure that
You really need it
You know how to implement it
I don't know of the first, and how the performance is crucial for you. But as for the second, you at least violated the rule of three. You class is very unsafe to use. If you copy it, the memory buffer will then be double-deleted.
You should not afraid to used STL containers, they are fast and optimized. At least the std::vector, it is as fast as the raw pointer in many scenarios. You can rewrite you class using std::vector as follows:
template <typename T>
class Matrix {
public:
typedef std::vector<T> MatrixRow;
typedef std::vector<MatrixRow> MatrixBody;
Matrix(int m, int n) : nRows(m), nCols(n), _body(m, MatrixRow(n)) {}
const MatrixBody& GetMatrix() const { return _body; }
const MatrixRow& GetRow(int i) const { return _body[i]; }
inline T Cell(int row, int col) const { return _body[row][col]; }
inline int GetNRows() const { return nRows; }
inline int GetNCols() const { return nCols; }
private:
int nRows, nCols;
MatrixBody _body;
};
Since this class is not using dynamic memory allocation, it is safe to copy and assign. You also don't need to explicitly store nRows and nCols in this case; you can use _body.size() and _body[0].size() instead.
Concerning underlying vector of vectors, it is dereferenced using the same [i][j] construction. It is easily iterated with begin() and end(). And if you absolutely need to use the raw pointer in some routine, you can always access it with &row[0].
The only possible difficulty is that you cannot easily convert MatrixBody to T**. But think it twice, maybe you don't really need to use T** at all.
Edit:
Note that my final purpose here is not having the class working, is just learning more about templates :-)
Suppose you have a template class which implements a vector:
template <typename T>
class Vector
{
public:
Vector(size_t dim) {
dimension = dim;
elements = new T[dim];
}
/* Here more stuff, like operator[] etc... */
private:
size_t dimension;
T * elements;
}
And suppose you want to build a matrix with it. A matrix is just a vector of vectors, thus it can be designed as follows:
template <typename T>
class Matrix : public Vector<Vector<T> >
{
/*...*/
}
And here comes trouble: In the constructor I need to provide rows and columns as parameter to the internal vectors. It should be something like
template <typename T>
Matrix<T>::Matrix (size_t ncols, size_t nrows)
: Vector<Vector<T> > /* Here I need to specify size for both
* internal and external vectors */
{
}
Obviously I cannot write Vector<Vector<T>(nrows)>(ncols), but that's what I would need!
A possible solution would be including size inside the template:
template <typename T, size_t N>
class Vector
{
public:
Vector() {
elements = new T[N];
}
/* Here more stuff, like operator[] etc... */
private:
T * elements;
}
Hence I would no longer need constructor parameters, but this also forces me to write clumsy code with templates everywhere (by exmample, every function using a Vector should be declared as
template <typename T, size_t N>
void foo (Vector<T,N> &vec) {...}
Do you have better solutions?
EDIT:
As solution I took inspiration from Mr Fooz's and chubsdad's posts. That's how I fixed the problem:
/* The RowAccess class is just an array wrapper which raises an exception
* if you go out of bounds */
template <typename T>
class RowAccess
{
public:
RowAccess (T * values, unsigned cols) : values(vals), cols(c) {}
T & operator[] (unsigned i) throw (MatrixError) {
if (i < cols) return values[i];
else throw MatrixError("Column out of bound");
}
private:
T * values;
unsigned cols;
};
template <typename T>
class Matrix
{
public:
Matrix (unsigned rows, unsigned cols) {...}
virtual ~Matrix () {...}
RowAccess<T> operator[] (unsigned row) {
if (row < rows) return RowAccess<T>(values + cols * row, cols);
else throw MatrixError("Row out of boundary");
}
private:
unsigned rows;
unsigned cols;
T * values;
};
Thanks a lot to everyone!
In OO terms, I would vote for "has" a relationship between Matrix and a Vector. A Matrix has vectors, rather than a Matrix "is a" vector, which means that Matrix should not derive from Vector.
EDIT 1: A small correction. "..which means that Matrix should not derive "publicly" from Vector". Private inheritance may be still fine.
Use placement-new like this (burried behind the uninitialized_fill call)
template <typename T>
class Vector
{
public:
Vector(size_t dim, T const& c = T()) {
dimension = dim;
elements =
static_cast<T*>(operator new(sizeof(T) * dim));
std::uninitialized_fill(elements, elements + dim, c);
}
/* Here more stuff, like operator[] etc... */
private:
size_t dimension;
T * elements;
};
Then you can call the constructor with Matrix::Vector(ncols, Vector<T>(nrows)) (you don't need to repeat the argument for the outer Vector, because Vector refers to Vector< Vector<T> > automatically since you inherit from the outer Vector. You need to make sure to call destructors manually before doing operator delete(elements) in the destructor then.
You might also want to embed the vector as a member, which i would probably prefer because I imagine not necessarily all operations of the outer vector make sense for a matrix. Then the initialization looks like m(ncols, Vector<T>(nrows)).
It should be noted that std::vector can also be used for this
template <typename T>
class Vector
{
public:
Vector(size_t dim, T const& c = T()):elements(dim, c)
{ }
private:
std::vector<T> elements;
};
This is an easy and safe way to accomplish that, and you get automatic memory management.
This isn't what you asked, but there's a good chance the matrix would be better of implemented as a single linear vector where you provide high-level access methods that do the indexing (e.g. elmLoc=row*ncols+col). This way you don't need to create and initialize a vector of vectors. You also don't need to worry about accidentally having some inner vectors of the differing size. All dense matrix implementations I have ever used use a single linear vector as the underlying implementation.
It depends on what you expect from your Vector (and Matrix) class.
Either you want the size to be determined at runtime, and in that case, I'd suggest adding a resize() function which would allow you to size the Vector in the constructor as you like.
template <typename T>
class Vector
{
public:
Vector(size_t dim) {
dimension = dim;
elements = new T[dim];
}
Vector() : dimension(0), elements(0) {} // you need default constructor
void resize(size_t dim) { // note: this could be implemented a lot better
T* new_elements=new T[dim];
for(int i=0; i<dim && i<dimension; i++)
new_elements[i]=elements[i];
delete [] elements;
elements=new_elements; dimension=dim;
}
/* Here more stuff, like operator[] etc... */
private:
size_t dimension;
T * elements;
}
You would then resize your Vectors in the Matrix constructor in a loop.
If you want the size of your vector or matrix to be determined at compile time, the best thing probably would be to use the template non-type argument as you suggested.