Possible memory leak without a virtual destructor?

2019-01-12 09:07发布

#include <iostream>
using namespace std;
class base
{
   int a;
 public: 
   base() {a =0;}
 };
 class derv :public base
 {
   int b;
  public:
   derv() {b =1;}
 };
 int main()
 {
    base *pb = new derv();
    delete pb;
 }

I don't have a virtual destructor in derv class, does it delete only base part of derv object??

3条回答
倾城 Initia
2楼-- · 2019-01-12 09:16

There is no memory leak in your code. There would have been a memory leak if you needed to free some memory in the derived class destructor.

查看更多
放荡不羁爱自由
3楼-- · 2019-01-12 09:24

It might.

Because base does not have a virtual destructor, your code exhibits undefined behavior. Anything might happen. It might appear to work as you expect. It might leak memory. It might cause your program to crash. It might format your hard drive.

A citation was requested. C++11 §5.3.5/3 states that, for a scalar delete expression (i.e., not a delete[] expression):

if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.

The static type (base) is different from the dynamic type (derv) and the static type does not have a virtual destructor, so the behavior is undefined.

查看更多
地球回转人心会变
4楼-- · 2019-01-12 09:37

In your source code there is no memory leak, since you don't have any member variable that is created dynamically.

Consider the modified example below Case 1:

#include <iostream>
using namespace std;
class base
{
   int a;
 public: 
   base() {a =0;}
   ~base() 
     {
       cout<<"\nBase Destructor called";

     }
 };
 class derv :public base
 {
   int *b;

  public:
   derv() { b = new int;}
  ~derv()
  {
      cout<<"\nDerv Destructor called"; 
      delete b;
  }
 };
 int main()
 {
    base *pb = new derv();
    delete pb;
 }

In this case the output will be,

   Base Destructor called

In this case there is a memory leak, because 'b' is created dynamically using 'new' which should be deleted using 'delete' keyword. Since derv destructor is not being called it's not deleted so there is memory leak.

Consider the below case 2:

#include <iostream>
using namespace std;
class base
{
   int a;
 public: 
   base() {a =0;}
   virtual ~base() 
     {
       cout<<"\nBase Destructor called";

     }
 };
 class derv :public base
 {
   int *b;

  public:
   derv() { b = new int;}
  ~derv()
  {
      cout<<"\nDerv Destructor called"; 
      delete b;
  }
 };
 int main()
 {
    base *pb = new derv();
    delete pb;
 }

In the case 2 output will be,

Derv Destructor called 
Base Destructor called

In this case there is no memory leak.because derv destructor is called and b is getting deleted.

Destructor can be defined as Virtual in base class to make sure the derived class destructor to be called when we delete base class pointer which is pointing to derived class object.

We can say 'Destructor must be virtual when derived class has dynamically created members'.

查看更多
登录 后发表回答