0
votes

My code contains two classes.

  class points{
            char *p;
    public: points(){cout<<"constructor points called"<<endl;p=new char();}
            virtual ~points(){cout<<"destructor points called"<<endl;delete(p);}
  };
  class otherpoints: public points{
                    points x1;
    public: otherpoints(){cout<<"constructor otherpoints called"<<endl;x1=points();}
            ~otherpoints(){cout<<"destructor otherpoints called"<<endl;}
  };
  int main(int argc, char *argv[])
  {
    otherpoints y1;

    return 0;
  }

Here I allocate a pointer in base class constructor and destroy memory of pointer in the respective base class destructor.

When I run the binary using valgrind, it gives error:-

constructor points called

constructor points called

constructor otherpoints called

constructor points called

destructor points called

destructor otherpoints called

destructor points called

==2209== Invalid free() / delete / delete[]

==2209==    at 0x4024851: operator delete(void*) (vg_replace_malloc.c:387)

==2209==    by 0x8048A36: points::~points() (in home/santosh/programs/c++/parent_child_conscall)

==2209==    by 0x8048BB2: otherpoints::~otherpoints() (in /home/santosh/programs/c++/parent_child_conscall)

==2209==    by 0x804889A: main (in /home/santosh/programs/c++/parent_child_conscall)

==2209==  Address 0x42d5098 is 0 bytes inside a block of size 1 free'd

==2209==    at 0x4024851: operator delete(void*) (vg_replace_malloc.c:387)

==2209==    by 0x8048A36: points::~points() (in /home/santosh/programs/c++/parent_child_conscall)

==2209==    by 0x8048B32: otherpoints::otherpoints() (in /home/santosh/programs/c++/parent_child_conscall)

==2209==    by 0x8048889: main (in /home/santosh/programs/c++/parent_child_conscall)

==2209==    destructor points called

==2209== 

==2209== HEAP SUMMARY:

==2209==     in use at exit: 1 bytes in 1 blocks

==2209==   total heap usage: 3 allocs, 3 frees, 3 bytes allocated

==2209== 

==2209== LEAK SUMMARY:

==2209==    definitely lost: 1 bytes in 1 blocks

==2209==    indirectly lost: 0 bytes in 0 blocks

==2209==      possibly lost: 0 bytes in 0 blocks

==2209==    still reachable: 0 bytes in 0 blocks

==2209==         suppressed: 0 bytes in 0 blocks

==2209== Rerun with --leak-check=full to see details of leaked memory

==2209== 

==2209== For counts of detected and suppressed errors, rerun with: -v

==2209== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 18 from 7)

Unable to know which 1 byte memory I am unable to deallocate.

Do I have to post the backtrace report?

Any help is thankful.

1
You need to give points an assignment operator and a copy constructor. Look up the rule of three.juanchopanza

1 Answers

3
votes

The problem here is that you create two instances of the points class. One temporary with points() and of course one with the declaration of x1.

When you do x1 = points() you create a temporary object with the points() construct, this is then copy-assigned to x1, and then the temporary object is destroyed. Since you do not provide a copy-assignment operator, the compiler will create one for you, but it simply copies the pointer, and don't allocate new memory. This means you for a while have two objects containing a pointer to the same memory. When the temporary object is destroyed you free the memory in the destructor, leaving the pointer in x1 dangling. When x1 is destroyed you try to delete this dangling pointer, leading to the double-free error.

The best way to solve this, is to implement a copy-assignment operator, and preferably a copy-constructor as well, and in those allocate new memory and copy the data.