c ++删除引用

时间:2010-12-12 01:29:18

标签: c++ memory-leaks

我还在学习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'表示释放的指针未分配。这样做的正确方法是什么?或者我做错了什么?由于矩阵太大而且迭代次数过多,我的大型硬盘驱动器空间不足,我只能假设我的内存泄漏很多。

5 个答案:

答案 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的规则基本相同。这就是你实现复制构造函数,赋值运算符和析构函数的原因:这样实际上你可以按照你合理的预期方式工作。