Reputation: 3761
I have a matrix class and, with the following constructor:
template<class T>
Matrix<T>::Matrix(unsigned rows, unsigned cols) :
rows(rows), cols(cols) {
index = 0;
data_ = new T[rows * cols];
}
template<class T>
Matrix<T>::~Matrix() {
delete[] data_;
}
When I'm calculating the inverse of the matrix, I would like to free the memory of the
temporary variable called a
:
template<class T>
Matrix<T> Matrix<T>::inverse() {
unsigned i, j, k;
Matrix<T> a(2 * rows, 2 * rows);
....
return tmp;
}
I thought that this variable would be destroyed in the end of the function, but when I test:
for (int i = 0; i < 3; i++) {
Matrix<double> m(5, 5);
m << 5, 2, 4, 5, 6, 1, 3, 1, 2, 5, 2, 5, 2, 7, 2, 9, 2, 1, 0.1, 0.43, 1, 0, 0, 0, 1;
m.inverse();
std::cout << m << std::endl;
}
In the first loop the a
is initialized with zeros, but the next step the initial values of the a
is the previous values, so a(k+1)=a_endvalues(k)
. Why is it like this?
Upvotes: 0
Views: 156
Reputation: 227418
The problem is that you are not initializing the elements of your dynamically allocated array in the constructor. To ensure that the array has default constructed or zero-initialized elements, you need to do this in your constructor:
template<class T>
Matrix<T>::Matrix(unsigned rows, unsigned cols) :
rows(rows), cols(cols) {
index = 0;
data_ = new T[rows * cols]();
// ^ HERE!
}
But as has been pointed out in comments, you could make your life easier by using an std::vector<T>
:
template<class T>
Matrix<T>::Matrix(unsigned rows, unsigned cols) :
rows(rows), cols(cols), data_(rows*cols)
{ }
Upvotes: 2
Reputation: 4114
The memory is freed and reallocated every time the function is called. The overlap of values is just chance. The new allocation could be at the same location as the old one. You can test this by making another parametrized constructor and passing separate initializer.
You can also test whether the destructor is called by writing an output statement.
Upvotes: 2
Reputation: 25497
The local variable 'a' is destroyed and the destructor releases the memory. However, when the memory was allocated again, it is just conincidental that the memory location has previous contents.
Upvotes: 1
Reputation: 70929
Initializing the array is a separate thing from allocating it.
Add debug output in your destructor to verify that it is called.
Also to initialize the array to zero maybe use memset:
memset(a, 0, rows * cols * sizeof(T));
Upvotes: 1
Reputation: 171127
The memory is indeed freed. And then allocated again in the next iteration of the loop. Not that your Matrix
constructor does not initialise the array to anything, so it just contains what happened to be stored in the memory which now belongs to it.
It's possible that in your particular case, the allocator places the second-iteration a.data_
at the same place where the first-iteration a.data_
was, so you still see the old values.
Upvotes: 3