开发者

Unable to nail memory leak detected by valgrind

开发者 https://www.devze.com 2023-02-07 14:36 出处:网络
Below is the pattern of new/delete operators in my program. Valgrind says that memory is \"definitely lost\". I couldn\'t quite get where the leak is. Is there something wrong with my usage of new/del

Below is the pattern of new/delete operators in my program. Valgrind says that memory is "definitely lost". I couldn't quite get where the leak is. Is there something wrong with my usage of new/delete operators.

 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();
    }

valgrind says that memory is lost.

==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)


You are not following the rule of three. If your class manages resources that need to be cleaned up, you must declare a destructor, copy constructor, and copy assignment operator. Neither of your classes has a copy constructor or a copy assignment operator.

Really, you should almost certainly just be using a smart pointer like unique_ptr from C++0x; shared_ptr from Boost, C++ TR1, and C++0x; or scoped_ptr from Boost.

The likely issue causing this specific problem is that you have forgotten to make the base-class GenericInterface destructor virtual, so the wrong destructor is being called and the MyClass object that you dynamically create in Specific is never destroyed.

deleteing an object via a pointer to one of its base classes results in undefined behavior if the base class destructor is not declared virtual (that means bad things will happen, ranging from memory leaks to crashes).


Your GenericInterface destructor probably is not virtual, so only the GenericInterface destructor is getting called when gInterface is destroyed.


Does your GenericInterface class declare a virtual destructor? If not, the Specific class's destructor won't get called, and thus the "delete _myClass" line won't be executed.

Just another way C++ makes your life more interesting :)


In your Generic class destructor you should also check the gInterface pointer before deleting it. If Create() is not called before the object is destroyed it will cause problems. If your c++ compiler doesn't throw on new failures your other class may also do the same thing

0

精彩评论

暂无评论...
验证码 换一张
取 消