我有一个矩阵类,并使用以下构造函数:
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)
。为什么会这样?
答案 0 :(得分:3)
记忆确实被释放了。然后在循环的下一次迭代中再次分配。并不是说你的Matrix
构造函数没有将数组初始化为任何东西,所以它只包含碰巧存储在现在属于它的内存中的内容。
在您的特定情况下,分配器可能会将第二次迭代a.data_
放置在第一次迭代a.data_
所在的同一位置,因此您仍然可以看到旧值。
答案 1 :(得分:2)
每次调用函数时都会释放并重新分配内存。价值重叠只是机会。新分配可以与旧分配位于同一位置。您可以通过创建另一个参数化构造函数并传递单独的初始化程序来测试它。
您还可以通过编写输出语句来测试是否调用析构函数。
答案 2 :(得分: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)
{ }
答案 3 :(得分:1)
初始化数组与分配数组是分开的。
在析构函数中添加调试输出以验证它是否被调用。
同样要将数组初始化为零,也可以使用memset:
memset(a, 0, rows * cols * sizeof(T));
答案 4 :(得分:1)
本地变量'a'被销毁,析构函数释放内存。但是,当再次分配内存时,内存位置具有以前的内容就是巧合。