2012-04-28 2 views
1

Ниже приведен пример класса, который доступен для операции +.Будет ли этот класс добавления причиной утечки памяти?

class A 
{ 
public: 
    int *array; 

    A() 
    { 
     array = new int[10]; 
    } 

    ~A() 
    { 
     delete[] array; 
    } 

    A operator+ (const A &b) 
    { 
     A c; 
     for(int i=0; i<10; i++) 
     c.array[i] += array[i] + b.array[i]; 
     return c; 
    } 
}; 

int main() 
{ 
    A a,b,c,d; 

    /* puts some random numbers into the arrays of b,c and d */ 
    a = b+c+d; 
} 

Будет a запустить деструктор перед копированием результата b+c+d или нет? Если нет, то как я могу убедиться, что нет утечки памяти?

Перегрузка оператора + разработана таким образом, что никакой операнд не изменяется.

+0

Что случилось с принятым ответом на [ваш предыдущий вопрос] (http://stackoverflow.com/q/10360232/78845)? И почему вы используете 'new int [10]', а не 'std :: vector'? – Johnsyweb

+0

Я предполагаю, что это всего лишь пример, чтобы попытаться понять, но если бы это был реальный код, вы могли бы просто определить 'int array [10];', и тогда не нужно беспокоиться о правильном удалении. – Corbin

+0

@Johnsyweb Ответ был замечательный, но это был просто пример, который я набросал без особого размышления. Этот пример не свидетельствует о моем взгляде на другие ответы. –

ответ

9

Вам необходимо добавить оператора равенства к A. Также вы будете likely want to create a copy constructor.

Когда a становится возвратом от b + c + d, указатель array в a переписывается без delete[], когда-либо вызываемого на нем. Вам нужно сделать оператор =, который удаляет array.

Пример оператора = ниже:

A& operator=(A const& a) 
{ 
    if (&a != this) { 
     int* tmp = this->array; 
     this->array = new int[10]; 
     //copy a.array to this->array 
     delete[] tmp; 
    } 
    return *this; 
} 

Там много тонкостей в этом, если вы новичок в operator=.

В частности, проверка или нет a равно this необходима, потому что это вполне допустимо, чтобы написать:

A a; 
a = a; 

Это приведет к бессмысленной копии, и в большинстве случаев operator= вызовет ошибку.

Другая тонкость является менее требовательной, чем один и более стиль кодирования (хотя и очень распространенный стандарт). При копировании чего-то, что динамически распределено, вы всегда хотите выделить и скопировать, прежде чем выпускать. Таким образом, если new выдает исключение (или что-то еще не получается), объект все еще находится в стабильном состоянии, хотя с его старыми данными вместо новых ожидаемых датированных.

+0

спасибо за отличный совет! –

+1

См. Также: http://stackoverflow.com/q/3279543/78845 – Johnsyweb

2

Будет ли это причиной утечки памяти?

Да, это будет. Вы забыли добавить экземпляр-конструктор и оператор присваивания. See Rule of Three

Вы также можете использовать std::vector<int> для A::array вместо int*. В этом случае вам не нужно будет беспокоиться о том, что оператор-конструктор/оператор копирования (пока вы не добавляете что-то еще, которое должно обрабатываться в destrcutor).

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