Kicsi Mano
Kicsi Mano

Reputation: 3761

How can I free memory in Matrix Class?

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

Answers (5)

juanchopanza
juanchopanza

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

asheeshr
asheeshr

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

Chubsdad
Chubsdad

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

Ivaylo Strandjev
Ivaylo Strandjev

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

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

Related Questions