返回新指针时的内存管理

时间:2014-01-19 15:52:53

标签: c++ memory-management

我有一个定义为

的方法
class1* class1::create(something)
{
    class1* a = new class1(*this);
    a->somemethod(something);
    return a;
}

我将其他地方称为

class1* b = c::create(something);

所以我的问题是这个泄密记忆?如果不是为什么?

3 个答案:

答案 0 :(得分:2)

是的,它会泄漏内存,除非调用者删除了b。为什么?因为每次拨打new都必须通过拨打delete进行匹配。

请注意,这是一种危险且异常的不安全模式:最好返回管理自己资源的内容,而不是将其放在调用方上。你可以返回一个智能指针(std::unique_ptr似乎是最合适的选项),或者只是按值返回class1实例,而不是返回一个指针。

更多关于为什么它是一个麻烦的接口:一个指针在C ++中可以是很多东西。它可以是指向您可能需要或可能不需要删除的实例的指针。它可以是指向数组中第一个元素的指针,可以动态分配也可以不动态分配。因此,来电者必须知道是否要拨打deletedelete[],或者根本不知道。这不考虑例外情况。如果在对class1::createdelete b的调用之间引发异常,则不会删除该对象。因此,使用管理自己资源的类型的重要性。

答案 1 :(得分:0)

如果最终你会打电话给delete b;它不会泄漏,否则就会泄密。

答案 2 :(得分:0)

如果抛出无异常,它不会泄漏内存,也不会指向未定义的位置。也许您认为,class1create的析构函数将被调用 - 事实并非如此,只有class1 *a将从堆栈中删除,并且它是内置类型。 new class1继续存在,直到您明确删除它为止。

但是当抛出异常时,可能会有内存泄漏,当class1在其构造函数动态内存中分配时,依赖于它由析构函数释放 - 这不会发生,因为如果示例中的new class1失败,class1的析构函数被调用! class1失败时,只会从堆中删除已为new class1成员变量分配的内存。

E.g。

class1* class1::create(something)
{
    class1* a = new class1(*this);
    a->somemethod(something);
    return a;
}

class1 *b = 0;
try
{
    b = c::create(something);
    delete b;
}
catch(...)
{
     delete b; // allright, no leak?
}

不保证无泄漏,如果class1看起来是像这样

class1
{
    int huge_var1[x][y][z];
    int huge_var2[x][y][z];
    int *huge_var3;
public:
    class1 (const class1 &c)
    {
        // bla bla bla
        huge_var3 = new int [x*y*z];
    }
    ~class1 ()
    {
        delete huge_var3;
    }
    // bla bla bla
};

当您的new class1失败时,huge_var1huge_var2将从堆中释放,而不是huge_var3指向的块。