首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >下面的代码会导致c++中的内存泄漏吗

下面的代码会导致c++中的内存泄漏吗
EN

Stack Overflow用户
提问于 2008-09-29 04:58:34
回答 5查看 12.8K关注 0票数 20
代码语言:javascript
复制
class someclass {};

class base
{
    int a;
    int *pint;
    someclass objsomeclass;
    someclass* psomeclass;
public:
    base()
    {
        objsomeclass = someclass();
        psomeclass = new someclass();
        pint = new int(); 
        throw "constructor failed";
        a = 43;
    }
}

int main()
{
    base temp();
}

在上面的代码中,构造函数抛出。哪些对象将被泄漏,如何避免内存泄漏?

代码语言:javascript
复制
int main()
{
    base *temp = new base();
}

上面的代码怎么样?在构造函数抛出后,如何避免内存泄漏?

EN

回答 5

Stack Overflow用户

发布于 2012-01-28 20:32:14

我认为顶部的答案是错误的,并且仍然会泄漏内存。如果类成员的析构函数抛出异常(因为它从未完成初始化,并且可能某些成员从未到达其构造函数调用),则不会调用该类成员的析构函数。它们的析构函数仅在类的析构函数调用期间调用。

这个简单的程序演示了这一点。

代码语言:javascript
复制
#include <stdio.h>


class A
{
    int x;

public:
    A(int x) : x(x) { printf("A constructor [%d]\n", x); }
    ~A() { printf("A destructor [%d]\n", x); }
};


class B
{
    A a1;
    A a2;

public:
    B()
    :   a1(3),
        a2(5)
    {
        printf("B constructor\n");
        throw "failed";
    }
    ~B() { printf("B destructor\n"); }
};


int main()
{
    B b;

    return 0;
}

输出如下(使用g++ 4.5.2):

代码语言:javascript
复制
A constructor [3]
A constructor [5]
B constructor
terminate called after throwing an instance of 'char const*'
Aborted

代码语言:javascript
复制
#include <stdio.h>


class A
{
    int x;

public:
    A(int x) : x(x) { printf("A constructor [%d]\n", x); }
    ~A() { printf("A destructor [%d]\n", x); }
};


class B
{
    A * a1;
    A * a2;

public:
    B()
    try  // <--- Notice this change
    :   a1(NULL),
        a2(NULL)
    {
        printf("B constructor\n");
        a1 = new A(3);
        throw "fail";
        a2 = new A(5);
    }
    catch ( ... ) {   // <--- Notice this change
        printf("B Cleanup\n");
        delete a2;  // It's ok if it's NULL.
        delete a1;  // It's ok if it's NULL.
    }

    ~B() { printf("B destructor\n"); }
};


int main()
{
    B b;

    return 0;
}

如果您运行它,您将得到预期的输出,其中只有分配的对象被销毁和释放。

代码语言:javascript
复制
B constructor
A constructor [3]
B Cleanup
A destructor [3]
terminate called after throwing an instance of 'char const*'
Aborted

代码语言:javascript
复制
class C
{
    std::shared_ptr<someclass> a1;
    std::shared_ptr<someclass> a2;

public:
    C()
    {
        std::shared_ptr<someclass> new_a1(new someclass());
        std::shared_ptr<someclass> new_a2(new someclass());

        // You will reach here only if both allocations succeeded. Exception will free them both since they were allocated as automatic variables on the stack.
        a1 = new_a1;
        a2 = new_a2;
    }
}
票数 1
EN

Stack Overflow用户

发布于 2008-09-29 05:01:20

是的,该代码会泄漏内存。使用"new“分配的内存块在引发异常时不会被释放。这是RAII背后的部分动机。

要避免内存泄漏,请尝试如下所示:

代码语言:javascript
复制
psomeclass = NULL;
pint = NULL;
/* So on for any pointers you allocate */

try {
    objsomeclass = someclass();
    psomeclass = new someclass();
    pint = new int(); 
    throw "constructor failed";
    a = 43;
 }
 catch (...)
 {
     delete psomeclass;
     delete pint;
     throw;
 }
票数 0
EN

Stack Overflow用户

发布于 2008-09-29 05:02:39

如果你抛出了一个构造函数,你应该清理掉在调用抛出之前的所有东西。如果你正在使用继承或者抛出一个析构函数,你真的不应该这样做。这种行为很奇怪(没有我的标准,但它可能是未定义的?)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/147572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档