2012-06-30 3 views
0

Что я думаю о том, что rvalue A, возвращенный SetVar, является идентичной копией Class и разделяет тот же указатель Var. но когда rvalue вызывает его деконструктор, он удаляет Class's Val.возвращение * это; удаляет указатели

class A 
{ 
private: 
    int* Var; 
public: 
    A SetVar(int); 
    ~A() 
    { 
     delete Var; 
    } 
}; 

A A::SetVar(int NewVar) 
{ 
    Var=new int; 
    *Var=NewVar; 
       //POINT A 
    return *this; 
} 

int main() 
{ 
    A Class; 
    Class.SetVar(8); 

       //POINT B 
} 

В POINT A*Val равно 8, но в POINT B*Val равна -17891602. Я также получаю _BLOCK_TYPE_IS_VALID (pHead-> nHeadUse) из-за попытки дважды удалить Val.

Удаление деконструктора решает проблему, но создает утечку памяти.

+0

Откуда вы знаете стоимость? Я чувствую, что вы считаете, что точка «B» на самом деле указывает «C» на другую сторону деструктора. Значение '-17891602' очень подозрительно выглядит« 0xFEEEFEEE ». См. Http://stackoverflow.com/a/127404/14065 Но есть и другие проблемы с кодом. –

+0

Это в значительной степени пример учебника о том, почему вам нужно реализовать глубокую копию и правило из трех. Вам нужна копия этого учебника. –

+0

Исправление учебника [правило три] (http://stackoverflow.com/a/4172724/636019). – ildjarn

ответ

6

Вы нарушили The Rule of Three

Таким образом, вы сделаете копию объекта, когда вы делаете

return *this 

который получает разрушенное производственное, а также, и delete вызывается дважды на одном указателе. Вы все равно не должны этого делать. Вы должны вернуть ссылку, но почему функция setter возвращает ссылку на объект, который он вызывал в любом случае? Isd это для цепочки вызовов функций?

Кроме того, вы теряете Var каждый раз, когда вы переназначаете его.

1

Здесь есть несколько проблем.

Во-первых, самая прямая причина вашей проблемы заключается в том, что объект объекта this создается, когда SetVar() возвращается. (Вероятно, вы захотите вернуть ссылку на A вместо.) Поскольку для класса A нет конструктора копирования, значения всех полей неявно копируются. Это означает, что копия будет иметь указатель на тот же самый параметр Var, который вы указали в SetVar. Другими словами, у вас будет два указателя на одну и ту же память, одну в исходной переменной A (тот, который вы вызываете «класс»), и один в копии, возвращаемой SetVar(). Когда второй из них будет уничтожен, его деструктор будет удалять память с уже удаленным указателем.

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