2013-03-12 2 views
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]; 
    } 
} 

Мне просто интересно, если вышеуказанный код будет протекать сам по себе. Есть ли какая-либо ситуация, когда он может протекать (кроме того, если я не вызвал удаление правильно)?Будет ли этот конкретный пример производить утечки памяти?

Спасибо.

+0

Возможно ли, чтобы конструктор 'A' выбрал исключение в этом конкретном примере? –

+0

Я думаю, что нет утечек памяти, но будет очень просто понять утечки, если вы создадите основной код. –

ответ

9

Да, возможно, если new выбрасывается в конструктор.

Деструктор тогда не будет запущен, и любые распределения, которые уже произошли, не будут выпущены.

Чтобы быть более конкретным: если какая-либо память была динамически распределена до возникновения исключения в конструкторе, утечка памяти произойдет, поскольку деструктор объекта не будет запущен.


Простая иллюстрация:

class Leaks 
{ 
private: 

    data* d; 

public: 

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

    ~Leaks() 
    { 
     delete data; 
    } 

}; 

Это недостатки конструкции. data всегда будет течь здесь. Вы ничего не можете с этим поделать. (Единственный случай, когда данные не будут утечки, будет, если new не удалось.)

С new сам может бросить, ваш примерный код способен метать после одного или нескольких распределений, тем самым оставляя вас с утечкой.

Есть три способа решения этим:

  • Не выделять память (в этой ситуации вы бы просто использовать вектор, но, очевидно, иногда нет никакого способа вокруг использования динамического распределения)
  • Марки уверенный, что ваш конструктор никогда не может бросить после любых распределений памяти, или если он бросает, чтобы очистить память перед бросанием. Это будет сделать некоторые довольно неприятный код, хотя во всех, кроме самых тривиальных конструкторами
  • Использование смарт-указатели
+0

Деструктор будет работать для тех объектов, для которых вызывается 'new'! –

+0

@Aniket: Нет, не будет. 'a' - это массив указателей * для' A', а не 'A'. –

+0

@Aniket no 'B :: ~ B' не запускается вообще, если' B :: B' throws; деструкторы выполняются только для полностью построенных объектов. –

1

Отсутствие утечек. Этот код в порядке - утечек нет.

1

Не может видеть никаких утечек или потенциальных утечек там. Единственный неприятный бит - это размер жестко заданного массива. Если вы хотите изменить динамику, вам может потребоваться изучить оператор delete [].

1

Кажется, что код правильный. Нет утечек.

Смежные вопросы