#ifndef DELETE
#define DELETE(var) delete var, var = NULL
#endif
using namespace std;
class Teste {
private:
Teste *_Z;
public:
Teste(){
AnyNum = 5;
_Z = NULL;
}
~Teste(){
if (_Z != NULL)
DELETE(_Z);
}
Teste *Z(){
_Z = new Teste;
return _Z;
}
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
int AnyNum;
};
int main(int argc, char *argv[]){
Teste *b = new Teste, *a;
a = b->Z();
cout << "a->AnyNum: " << a->AnyNum << "\n";
b->Z(new Teste);
cout << "a->AnyNum: " << a->AnyNum << "\n";
//wdDELETE(a);
DELETE(b);
return 0;
}
我想知道这段代码是否有内存泄漏
它工作正常,*a
被设置两次并且 AnyNum
在每个 cout <<
上打印不同的数字
但我想知道 _Z
发生了什么在 setter(new Teste
)之后,我对指针/引用的了解还不多,但是对于逻辑,我猜它正在被交换为新变量
如果它正在泄漏,是否可以在不将 a 设置为 _Z
的情况下完成此操作?再次?
因为地址没有改变,只是直接分配的内存
我打算使用 *&
而不仅仅是指针,但它会有所作为吗?
最佳答案
这一行内存泄漏:
b->Z(new Teste);
因为函数的定义:
void Z(Teste *value){
value->AnyNum = 100;
*_Z = *value;
}
看起来 Z 没有参数应该是一个 getter 而有参数是一个 setter。我怀疑你打算这样做:
void Z(Teste *value){
value->AnyNum = 100;
_Z = value;
}
(注意第三行)也就是说,将指针“值”分配给指针“_Z”,而不是将指向的值复制到 Z 指向的值之上。这样,第一个内存泄漏将得到解决,但代码仍然会有一个,因为 _Z 可能持有一个指针。所以你必须这样做:
void Z(Teste *value){
value->AnyNum = 100;
delete _Z; // you don't have to check for null
_Z = value;
}
正如另一条评论中提到的,真正的解决方案是使用智能指针。这是对相同代码的更现代的方法:
using namespace std;
class Teste {
private:
boost::shared_ptr<Teste> Z_;
public:
Teste() : AnyNum(5), Z_(NULL)
{ }
boost::shared_ptr<Teste> Z()
{
Z_.reset(new Teste);
return Z_;
}
void Z(boost::shared_ptr<Teste> value)
{
value->AnyNum = 100;
Z_ = value;
}
int AnyNum;
};
int main(int argc, char *argv[]){
boost::shared_ptr<Teste> b = new Teste, a;
a = b->Z();
cout << "a->AnyNum: " << a->AnyNum << "\n";
b->Z(boost::shared_ptr<Teste>(new Teste));
cout << "a->AnyNum: " << a->AnyNum << "\n";
return 0;
}
关于c++ - 指针和引用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1543761/