Невозможно обнаружить утечку памяти, обнаруженную Valgrind - PullRequest
1 голос
/ 29 января 2011

Ниже приведен шаблон новых / удаляемых операторов в моей программе.Вальгринд говорит, что память «определенно потеряна».Я не мог понять, где находится утечка.Что-то не так с моим использованием операторов new / delete.

 class Generic
 {
        GenericInterface *gInterface; //GenericInterface is abstract class

        public:
           Generic ()
           {
                gInterface = NULL;
           }
           ~Generic ()
           {
               delete gInterface;
           }
           void Create()
           {
           gInterface = new Specific();
           }
    };

    class Specific : public GenericInterface
    {
       MyClass* _myClass; 

    public:
      Specific()
      {
         _myClass = new MyClass;
      }

      ~Specific()
      {
         delete _myClass; 
      }

    };

    int main()
    {
       Generic g;
       g.Create();
    }

Вальгринд говорит, что память потеряна.

==2639== 8 bytes in 1 blocks are definitely lost in loss record 2 of 45
==2639==    at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==2639==    by 0x804D77C: Specific::Specific() (Specific.cc:13)
==2639==    by 0x804DAFC: Generic::Create() (Generic.cc:58)

Ответы [ 4 ]

11 голосов
/ 29 января 2011

Вы не следуете правилу из трех .Если ваш класс управляет ресурсами, которые необходимо очистить, вы должны объявить деструктор, конструктор копирования и оператор назначения копирования.Ни один из ваших классов не имеет конструктора копирования или оператора присваивания копии.

Действительно, вы почти наверняка должны просто использовать умный указатель, такой как unique_ptr из C ++ 0x;shared_ptr от Boost, C ++ TR1 и C ++ 0x;или scoped_ptr от Boost.

Вероятная проблема, вызывающая эту конкретную проблему, заключается в том, что вы забыли создать базовый класс GenericInterface деструктор virtual, поэтому вызывается неправильный деструктор и MyClass объект, который вы динамически создаете в Specific, никогда не уничтожается.

delete использование объекта через указатель на один из его базовых классов приводит к неопределенному поведению, если деструктор базового класса не объявлен virtual (это означает, что могут произойти плохие вещи, от утечек памяти до сбоев).

2 голосов
/ 29 января 2011

Ваш деструктор GenericInterface, вероятно, не является виртуальным, поэтому при уничтожении gInterface вызывается только деструктор GenericInterface.

0 голосов
/ 29 января 2011

В вашем деструкторе Generic class вы также должны проверить указатель gInterface перед его удалением. Если Create () не вызывается до уничтожения объекта, это вызовет проблемы. Если ваш компилятор c ++ не генерирует новые сбои, ваш другой класс также может сделать то же самое

0 голосов
/ 29 января 2011

Ваш класс GenericInterface объявляет виртуальный деструктор? В противном случае деструктор класса Specific не будет вызван, и, таким образом, строка «delete _myClass» не будет выполнена.

Просто еще один способ, которым C ++ делает вашу жизнь интереснее:)

...