0

我有一个矩阵类,并且具有以下构造函数:

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_;
}

当我计算矩阵的逆时,我想释放名为的临时变量的内存a

template<class T>
Matrix<T> Matrix<T>::inverse() {
    unsigned i, j, k;
    Matrix<T> a(2 * rows, 2 * rows);        
    ....
    return tmp;
}

我以为这个变量会在函数结束时被销毁,但是当我测试时:

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;
    }

在第一个循环中a用零初始化,但下一步 的初始值a是之前的值,所以a(k+1)=a_endvalues(k). 为什么会这样?

4

5 回答 5

3

内存确实被释放了。然后在循环的下一次迭代中再次分配。并不是说您的Matrix构造函数没有将数组初始化为任何内容,因此它只包含碰巧存储在现在属于它的内存中的内容。

在您的特定情况下,分配器可能会将第二次迭代a.data_放置在第一次迭代所在的相同位置a.data_,因此您仍然会看到旧值。

于 2012-11-23T12:39:51.703 回答
2

每次调用函数时都会释放并重新分配内存。价值观的重叠只是偶然。新分配可能与旧分配位于同一位置。您可以通过创建另一个参数化构造函数并传递单独的初始化程序来测试它。

您还可以通过编写输出语句来测试是否调用了析构函数。

于 2012-11-23T12:43:22.843 回答
2

问题是您没有在构造函数中初始化动态分配的数组的元素。要确保数组具有默认构造或零初始化元素,您需要在构造函数中执行此操作:

template<class T>
Matrix<T>::Matrix(unsigned rows, unsigned cols) :
        rows(rows), cols(cols) {
    index = 0;
    data_ = new T[rows * cols]();
                //             ^ HERE!
}

但正如评论中指出的那样,您可以通过使用来让您的生活更轻松std::vector<T>

template<class T>
Matrix<T>::Matrix(unsigned rows, unsigned cols) :
        rows(rows), cols(cols), data_(rows*cols) 
{ }
于 2012-11-23T13:03:07.317 回答
1

初始化数组与分配数组是分开的。

在您的析构函数中添加调试输出以验证它是否被调用。

也可以使用 memset 将数组初始化为零:

memset(a, 0, rows * cols * sizeof(T));
于 2012-11-23T12:40:20.247 回答
1

局部变量“a”被销毁,析构函数释放内存。但是,当再次分配内存时,内存位置有以前的内容只是偶然的。

于 2012-11-23T12:42:50.843 回答