我知道我不能得到一个局部变量的参考。例如:
int& func1()
{
int i;
i = 1;
return i;
}我知道这是正确的,但是我必须在调用func2()之后删除它。
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int *p = func2();
cout << *p << endl;
delete p;
return 0;
}如果函数是这样的,则为:
MyClass MyFunction()
{
return new MyClass;
}MyClass的整个定义是:
class MyClass
{
public:
MyClass() : num(1){}
MyClass(MyClass*) : num(10){}
int num;
};这会导致内存泄漏吗?
我该怎么避免呢?函数返回一个对象而不是指针,那么我如何删除它呢?
PS:代码来自于“反思性对C++”第10章。原始代码是:
Picture frame(const Pictrue& pic)
{
// Picture has a constructor Picture(*P_Node)
// Frame_Pic derives from P_Node
// So the constructor Picture(*P_Node) will implicitly convert Frame_Pic to Picture.
return new Frame_Pic(pic);
}发布于 2011-12-08 13:03:12
使用具有指针构造函数的更新后的MyClass,我认为您应该编写:
MyClass MyFunction() {
MyClass *ptr = new MyClass;
MyClass retval(ptr);
delete ptr; // the dynamically-allocated object isn't needed any more
return retval;
}这碰巧是异常安全的,因为MyClass的构造函数不能抛出,但是通常情况下,如果不将结果直接放入智能指针中,就不应该调用new:
MyClass MyFunction() {
std::unique_ptr<MyClass>(new MyClass);
return MyClass(ptr);
}无论如何,这是一种相当荒谬的情况--如果您要按价值返回,则根本没有理由调用new:
MyClass MyFunction() {
MyClass tmpvalue;
return &tmpvalue; // doesn't actually return the pointer, just an object
// constructed from it
}而且,由于指针的值甚至没有被指针构造函数使用,所以您也可以编写:
MyClass MyFunction() {
return 0; // returns an object constructed from a null pointer
}在您从书中引用的原始代码中,我猜类Picture有一个P_Node*类型的数据成员,它在其中存储指针值,并在其析构函数中对该指针调用delete。希望作者还能对Picture的复制构造函数和复制赋值操作符做些什么,以防止复制后出现双空闲。我没有这本书,所以我无法检查我的猜测,但是Picture的代码应该显示它是如何完成的。
编辑:哦,那是科尼格和穆伊的书之一。它们(比)更有能力,因此它们的Picture类非常肯定地正确地处理资源。如果没有,那是因为这是一个故意做错事的例子。
发布于 2011-12-08 11:35:31
MyClass MyFunction()
{
return new MyClass;
} 这实际上是wrong.you正在返回一个指针。所以它应该是
MyClass* MyFunction()如果您的函数像我前面提到的那样,如果您在使用it.it之后不删除它,则会泄漏内存。
我该怎么避免呢?函数返回一个对象而不是指针,那么我如何删除它呢?
这是一个编译error.so,删除它的意义不会上升。
发布于 2011-12-08 11:34:56
如果删除函数返回的指针,则没有内存泄漏。但是,这很容易出错,因为这意味着函数的每个客户端都必须知道它应该删除返回值。使用智能指针(根据语义使用shared_ptr或unique_ptr )要好得多。
Picture示例也是如此。如果该对象正确地管理其资源(即删除析构函数中的内容,并且具有良好的复制构造函数和operator= )(按照三条规则,则不会出现内存泄漏。
https://stackoverflow.com/questions/8430307
复制相似问题