将下面的代码导致c ++中的内存泄漏 [英] Will the below code cause memory leak in c++

查看:96
本文介绍了将下面的代码导致c ++中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class someclass {}; 

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

int main()
{
base temp();
}

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

  int main()
{
base * temp = new base();
}

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

解决方案

当构造函数抛出时,不会调用析构函数(在这种情况下,你不显示析构函数释放动态分配的对象,但是假设你有一个)。



这是使用智能指针的一个主要原因 - 因为智能poitners是完全成熟的对象,他们将在异常堆栈展开期间获得调用的析构函数,并有机会释放



如果你使用类似Boost的scoped_ptr<>模板,你的类可能看起来更像:



<$> p $ p> class base {
int a;
scoped_ptr< int>品脱;
someclass objsomeclass;
scoped_ptr< someclass> psomeclass;
base():
pint(new int),
objsomeclass(s​​omeclass()),
psomeclass(new someclass())

b $ b throwconstructor failed;
a = 43;
}
}

您将没有内存泄漏dtor也会清除动态内存分配)。






希望这也回答了有关

  base * temp = new base(); 

p>

语句):



当在构造函数中抛出异常时,您应该注意到在正确处理可能在对象的异常终止构造中发生的资源分配方面:


  1. 析构函数

  2. 该对象类中包含的成员对象的析构函数将被调用


这意味着如果你的对象拥有资源,你有两种方法可用以清理在构造函数抛出时可能已经获取的那些资源:


  1. 捕获异常,释放资源,然后重新抛出。这可能很难正确,并可能成为维护问题。

  2. 使用对象来管理资源生命周期(RAII),并使用这些对象作为成员。当您的对象的构造函数抛出异常时,成员对象将调用结构体,并有机会释放其负责生命周期的资源。


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();
}

In the above code, the constructor throws. Which objects will be leaked, and how can the memory leaks be avoided?

int main()
{
    base *temp = new base();
}

How about in the above code? How can the memory leaks be avoided after the constructor throws?

解决方案

Yes it will leak memory. When the constructor throws, no destructor will be called (in this case you don't show a destructor that frees the dynamically allocated objects, but lets assume you had one).

This is a major reason to use smart pointers - since the smart poitners are full fledged objects, they will get destructors called during the exception's stack unwind and have the opportunity to free the memory.

If you use something like Boost's scoped_ptr<> template, your class could look more like:

class base{
    int a;
    scoped_ptr<int> pint;
    someclass objsomeclass;
    scoped_ptr<someclass> psomeclass;
    base() : 
       pint( new int),
       objsomeclass( someclass()),
       psomeclass( new someclass())

    {
        throw "constructor failed";
        a = 43;
    }
}

And you would have no memory leaks (and the default dtor would also clean up the dynamic memory allocations).


To sum up (and hopefully this also answers the question about the

base* temp = new base();

statement):

When an exception is thrown inside a constructor there are several things that you should take note of in terms of properly handling resource allocations that may have occured in the aborted construction of the object:

  1. the destructor for the object being constructed will not be called.
  2. destructors for member objects contained in that object's class will be called
  3. the memory for the object that was being constructed will be freed.

This means that if your object owns resources, you have 2 methods available to clean up those resources that might have already been acquired when the constructor throws:

  1. catch the exception, release the resources, then rethrow. This can be difficult to get correct and can become a maintenance problem.
  2. use objects to manage the resource lifetimes (RAII) and use those objects as the members. When the constructor for your object throws an exception, the member objects will have desctructors called and will have an opportunity to free the resource whose lifetimes they are responsible for.

这篇关于将下面的代码导致c ++中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆