我还在学习c ++并且有一个可能很明显的问题,或者我可能只是不知道自己要做什么。我有一些函数,它接受一个矩阵(我写的一个类,它有一个正确编写的析构函数)并从中创建一个新矩阵,返回对新矩阵的引用。我需要在这些矩阵上迭代数万次,所以我需要确保没有任何内存泄漏。所以,问题是,如何正确删除我不再需要的矩阵,以便为下一个矩阵腾出空间?这是我试图获得无泄漏的代码:
DynamicMatrix<double> x0 = getX0(n);
DynamicMatrix<double>exactU = getExactU(n);
DynamicMatrix<double> b = getB(n) * w;
DynamicMatrix<double> x1 = getX1(x0, b, w, n);
while( !isConverged(exactU,x1,e) ){
delete x0; //<<<<< This doesn't work. Nor does delete &x0.
x0 = x1;
x1 = getX1(x0, b, w, n);
}
每个getX()方法都创建一个指向矩阵的指针,并返回对矩阵的引用,如getX0():
DynamicMatrix<double> &getX0(int n){
DynamicMatrix<double>* mat1 = new DynamicMatrix<double>(n * n,1);
for (int i = 1 ; i <= n; i++){
for (int j = 1; j <= n; j++){
mat1->set((i-1)*n +j, 1, 0);
}
}
return *mat1;
}
然后,调用'delete X0'错误,因为它需要一个指针。 'delete&amp; X0'表示释放的指针未分配。这样做的正确方法是什么?或者我做错了什么?由于矩阵太大而且迭代次数过多,我的大型硬盘驱动器空间不足,我只能假设我的内存泄漏很多。
答案 0 :(得分:6)
Stroustrup R'lyeh Fhtagn 。
编写MyType myVar = MyFunction()
使用构造函数创建一个全新的对象,该构造函数接受返回类型myFunction
作为参数。然后丢弃myFunction
返回的内容 - 在您的示例中,getX0
返回对动态分配的对象的引用,因此泄露。
但是,说真的 - 尝试在堆栈上创建矩阵(没有new
)并按原样返回它们。不应该造成太大的麻烦,因为他们似乎无论如何动态地在内部分配他们的数据,我怀疑NRVO将适用于避免复制(返回的矩阵将被直接构造到适当的位置。{{1}底部的x0
魔法可以按如下方式实现:
x1
由于交换操作可以在指针交换(非常快)而不是实际数据副本的情况下在动态矩阵上实现,因此这应该非常快。
答案 1 :(得分:2)
你应该使用指针。声明
DynamicMatrix<double> x0 = getX0(n);
制作矩阵的副本。你想要
DynamicMatrix<double> *getX0(int n){
DynamicMatrix<double>* mat1 = new DynamicMatrix<double>(n * n,1);
...
return mat1;
}
然后
DynamicMatrix<double> *x0 = getX0(n);
...
delete x0;
答案 2 :(得分:1)
如果getX()
返回指针,则应写为第一行:
DynamicMatrix<double>* x0 = getX0(n);
当你返回一个新指针时,这会更有意义。然后你必须删除它,因为你在下面显示了一些行。
但请注意,使用boost::shared_ptr
:
typedef boost::shared_ptr<DynamicMatrix<double> > dyn_matrix_ptr;
dyn_matrix_ptr x0 (getX0(n));
// use x0 as a normal pointer
...
// You don't have to manually delete it, it will be deleted automatically.
答案 3 :(得分:0)
你的错误在这里:
DynamicMatrix<double> x0 = getX0(n);
你不一定要使用指针。您可以返回对新建对象的引用。要删除内存,只需获取引用的地址。使用引用的地址为您提供引用的地址;你应该可以打电话了
// receive newed memory in a reference
DynamicMatrix<double>& x0 = getX0(n);
// &x0 should give you the address of the allocated memory.
delete &x0;
答案 4 :(得分:0)
DynamicMatrix<double>
的规则与int
的规则基本相同。
如果它在堆栈上被分配为'auto'变量,那么清理它的正确方法是什么也不做 - 只是让它超出范围。您希望尽可能安排代码,以便实现这种情况。
如果分配了“新”,请使用“删除”进行清理。
请不要动态分配内容,然后通过引用返回。返回指针。实际上,也不要这样做。使用智能指针类。请。
如果您不需要,请不要动态分配内容。只需创建一个本地值,然后返回 - 按值(这就是你如何处理无法返回对非静态本地的引用这一事实)。对于编写如下代码,您永远不会思考,对吗?
int& give_me_a_value() {
int* result = new int(rand());
return *result;
}
再次:DynamicMatrix<double>
的规则与int
的规则基本相同。这就是你实现复制构造函数,赋值运算符和析构函数的原因:这样实际上你可以按照你合理的预期方式工作。