C ++,这会导致内存泄漏吗?

时间:2011-12-08 11:29:38

标签: c++ local-variables

我知道我无法获得本地var的引用。如:

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:代码来自“Ruminations on 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);
}

6 个答案:

答案 0 :(得分:3)

MyClass MyFunction() 
{     
return new MyClass; 
} 

这实际上是错误的。你正在返回一个指针。 所以它应该是

MyClass* MyFunction()

如果你的功能如上所述,如果你在使用它之后没有删除它。它会泄漏内存。

我应该如何避免它?该函数返回一个对象而不是一个指针,那么如何删除它呢?

这是一个编译错误。所以删除它的点不会上升

答案 1 :(得分:2)

如果删除从函数返回的指针,则没有内存泄漏。但是这很容易出错,因为这意味着函数的每个客户端都必须知道它应该删除返回值。根据语义使用智能指针(shared_ptrunique_ptr)会更好。

同样适用于Picture示例。如果此对象正确管理其资源(即在析构函数中删除并具有良好的复制构造函数和operator=(根据Rule of Three),则没有内存泄漏。

答案 2 :(得分:1)

使用具有指针构造函数的更新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的代码应该显示它是如何完成的。

<编辑:哦,这是Koenig和Moo的书之一。他们(超过)胜任,所以他们的Picture类正确处理资源。如果没有,那是因为它是故意做错的一个深思熟虑的例子。]

答案 3 :(得分:0)

这是一个简单的检查:

  • 如果您在程序中使用Nnew个数,那么您必须使用N兼容 1 <程序中的/ sup> delete以避免内存泄漏 2
你正在那样做吗?是的,在第一种情况下(你正在做new int),你就是这样做的。没有内存泄漏。

其余的帖子对我来说还不够明确!


1。通过兼容 delete,我的意思是如果您以new的形式使用ptr = new T[M],则兼容的delete应为delete []ptr。同样,delete ptrptr = new T兼容。

2。当然,如果您使用的是智能指针,那么您不必明确使用delete

答案 4 :(得分:0)

它与你的“func2”示例相同。谁曾经称之为“框架”,最终需要释放返回的图片。

答案 5 :(得分:0)

MyClass MyFunction()
{
    return new MyClass;
}

是不正确的,因为operator new返回一个指向MyClass的指针,但是你的函数返回MyClass,而不是MyClass *