c++;删除引用 我还在学习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); } DynamicMatrix x0=getX0(n); 动态矩阵xexactu=getExactU(n); 动态矩阵b=getB(n)*w; 动态矩阵x1=getX1(x0,b,w,n); 而(!isconvered(exactU,x1,e)){ delete x0;//

c++;删除引用 我还在学习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); } DynamicMatrix x0=getX0(n); 动态矩阵xexactu=getExactU(n); 动态矩阵b=getB(n)*w; 动态矩阵x1=getX1(x0,b,w,n); 而(!isconvered(exactU,x1,e)){ delete x0;//,c++,memory-leaks,C++,Memory Leaks,如果getX()返回指针,则应将其作为第一行写入: DynamicMatrix<double>* x0 = getX0(n); 你应该使用指针。语句 DynamicMatrix<double> x0 = getX0(n); DynamicMatrix x0=getX0(n); 复制一份矩阵,你想要吗 DynamicMatrix<double> *getX0(int n){ DynamicMatrix<double>* mat1 = new

如果
getX()
返回指针,则应将其作为第一行写入:

DynamicMatrix<double>* x0 = getX0(n);

你应该使用指针。语句

DynamicMatrix<double> x0 = getX0(n);
DynamicMatrix x0=getX0(n);
复制一份矩阵,你想要吗

DynamicMatrix<double> *getX0(int n){
  DynamicMatrix<double>* mat1 = new DynamicMatrix<double>(n * n,1);
  ...
  return mat1;
}
DynamicMatrix*getX0(int n){
DynamicMatrix*mat1=新的DynamicMatrix(n*n,1);
...
返回mat1;
}
然后

DynamicMatrix*x0=getX0(n);
...
删除x0;
您的错误在这里:

DynamicMatrix<double> x0 = getX0(n);
DynamicMatrix 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;
//接收引用中的新内存
动态矩阵&x0=getX0(n);
//&x0应提供分配内存的地址。
删除&x0;

Stroustrup R'lyeh Fhtagn

写入
MyType myVar=MyFunction()
使用接受返回类型为
myFunction
作为参数的构造函数创建一个全新的对象。然后丢弃
myFunction
返回的任何内容-在您的示例中,
getX0
返回对动态分配的对象的引用,因此会泄漏

不过,说真的-尝试在堆栈上创建矩阵(不使用
new
)并按原样返回。这不会造成太多麻烦,因为它们似乎在内部动态分配数据,我怀疑NRVO会应用于避免复制(返回的矩阵将直接构造到适当的位置。底部的
x0
x1
魔术可以实现如下:

x0.swap(x1);
DynamicMatrix<double> temp = getX1(x0, b, w, n);
x1.swap(temp);
x0.swap(x1);
动态矩阵温度=getX1(x0,b,w,n);
x1.交换(临时);

由于交换操作可以通过指针交换(速度非常快)而不是实际的数据拷贝在动态矩阵上实现,因此速度应该非常快。
DynamicMatrix
的规则基本上与
int
的规则相同

如果它是作为一个“自动”变量分配到堆栈上的,那么清理它的正确方法就是什么都不做——只是让它超出范围。您希望尽可能多地安排代码,这样就可以了

如果分配了“新建”,请使用“删除”将其清除

请不要动态分配某个对象,然后通过引用返回它。返回指针。实际上,也不要这样做。请使用智能指针类

如果不需要,请不要动态分配内容。只需创建一个本地值,然后按值返回它-(这就是您如何处理无法返回对非静态本地的引用这一事实的方法)。您永远不会思考编写如下代码,对吗

int& give_me_a_value() {
    int* result = new int(rand());
    return *result;
}

再次说明:
DynamicMatrix
的规则基本上与
int
的规则相同。这就是为什么要实现复制构造函数、赋值运算符和析构函数:这样实际上就可以按照您合理预期的方式工作。

好的,但是现在我如何做x0=x1,以便每个都指向一个单独的副本?@JakeVA:
删除x0;x0=新的DynamicMatrix(x1)
@JakeVA:但是你不想要副本,你想要移交所有权。那么我如何移交所有权?使用.swap?使用指针,移交所有权没有任何明确的要求。只需执行x0=x1并停止使用x1。确保每个分配只删除一次的所有工作都在你的手中。像auto\ptr这样的东西可以帮助somewhat.确保将分配要求放在函数规范中(例如,“getX0返回调用方必须删除的新分配矩阵”)。为矩阵类实现交换绝对是个好主意。但最后两行可以写成
getX1(x0,b,w,n)。交换(x1);
,这是一种常见的交换局部变量内容和函数返回的方式。my matrix类动态地将数据存储在堆上-我需要重写交换函数吗?或者它应该像您描述的那样工作,而不需要我自己编写?如果您的硬盘驱动器内存空间不足y leak,这意味着您的分页文件被配置为增长过大。您给出的示例..我仍在尝试整理引用和指针之间的差异,并在它们之间进行转换。坦率地说,是的,我可能会编写这样的代码。这就是我对矩阵类所做的,我认为这是正确的。我想这对我来说并不直观转换引用会创建一个副本。好吧…看看下面的代码:
int给我一个值(){int result=rand();return result;
这看起来不是很正常吗?我真的很希望如此,否则你一直在从非常非常奇怪的参考资料中学习。返回引用不会创建副本-这就是重点。按值返回会。通常,当函数返回某个引用时,它应该是r在函数运行时重新引用已存在的内容
// receive newed memory in a reference
DynamicMatrix<double>& x0 = getX0(n);

// &x0 should give you the address of the allocated memory.
delete &x0;
x0.swap(x1);
DynamicMatrix<double> temp = getX1(x0, b, w, n);
x1.swap(temp);
int& give_me_a_value() {
    int* result = new int(rand());
    return *result;
}