1
class A // blah blah generic abstracty whatever
{
  public:
  A();
  ~A();
};

class B
{
  public:
  B();
  ~B();

  private:
  A* a[8];
};

B::B()
{
  for(int x = 0; x < 8; x++)
  {
    a[x] = new A;
  }
}

B::~B()
{
  for(int x = 0; x < 8; x++)
  {
    delete a[x];
  }
}

我只是好奇上面的代码是否会自行泄漏。是否有任何可能泄漏的情况(除了我没有正确调用删除)?

谢谢。

4

4 回答 4

9

new的,如果在构造函数中抛出它是可能的。

然后析构函数将不会运行,并且已经发生的任何分配都不会被释放。

更具体地说:如果在构造函数发生异常之前已经动态分配了任何内存,则会发生内存泄漏,因为对象的析构函数不会运行。


一个简单的例子:

class Leaks
{
private:

    data* d;

public:

    Leaks()
    {
        data = new int;
        throw 1;
    }

    ~Leaks()
    {
        delete data;
    }

};

这是一个有缺陷的设计。data总会漏到这里。你对此无能为力。(数据不会泄漏的唯一情况是new失败。)

由于new它本身可以抛出,因此您的示例代码能够在一个或多个分配后抛出,从而给您留下泄漏。

有三种方法可以解决这个问题:

  • 不要分配内存(在这种情况下,您只需使用向量,但显然有时无法使用动态分配)
  • 确保您的构造函数永远不会在任何内存分配之后抛出,或者如果它确实抛出以在抛出之前清理内存。尽管除了最微不足道的构造函数之外,这将产生一些非常讨厌的代码
  • 使用智能指针
于 2013-03-12T06:14:39.807 回答
1

看来代码是正确的。没有泄漏。

于 2013-03-12T06:19:42.507 回答
1

没有泄漏。这段代码很好 - 没有泄漏。

于 2013-03-12T06:14:23.367 回答
1

那里看不到任何泄漏或潜在泄漏。唯一令人讨厌的一点是硬编码的数组大小。如果要将其更改为动态,则可能需要查看 delete[] 运算符。

于 2013-03-12T06:15:17.090 回答