Thursday 20 October 2016

class - double free or corruption (fasttop) -- c++



I just came across a strange problem. I will paste the full code below:





#include 

#include
#include

using namespace std;

// declare a base class
class Base
{
public:
Base();

Base(int n, int arr[2]);
Base(const Base &base);

Base &operator=(const Base &rhs);

int getSize() const;
int *getA() const;

~Base();


private:
int *a;
int size;
};

class Case
{
public:
Case();
Case(int n, int arr[2]);

Case(const Case &rhs);

Case &operator=(const Case &rhs);

int getSize() const;
int *getA() const;

~Case();

private:

int *a;
int size;
};

class Dase
{
public:
Dase();
Dase(int bSize, int barr[2], int cSize, int carr[2]);
Dase(const Dase &dase);


Dase &operator=(const Dase &rhs);

Base getB() const;
Case getC() const;

~Dase();

private:
Base b;

Case c;
};

// implementation
Base::Base() : size(0)
{
a = NULL;
}

Base::Base(int n, int arr[2]) : size(n)

{
a = new int[n];
for (int i = 0; i < size; i++)
a[i] = arr[i];
}

Base::Base(const Base &base)
{
size = base.getSize();


a = new int[size];
for (int i = 0; i < size; i++)
a[i] = base.getA()[i];
}

Base &Base::operator=(const Base &rhs)
{
if (this == &rhs)
return *this;


size = rhs.getSize();
delete[] a;
a = new int[size];
for (int i = 0; i < size; i++)
a[i] = rhs.getA()[i];
return *this;
}

int *Base::getA() const
{

return a;
}

int Base::getSize() const
{
return size;
}

Base::~Base()
{

delete[] a;
}

Case::Case() : size(0)
{
a = NULL;
}

Case::Case(int n, int arr[2]) : size(n)
{

a = new int[n];
for (int i = 0; i < size; i++)
a[i] = arr[i];
}

Case::Case(const Case &rhs)
{
size = rhs.getSize();

a = new int[size];

for (int i = 0; i < size; i++)
a[i] = rhs.getA()[i];
}

Case &Case::operator=(const Case &rhs)
{
if (this == &rhs)
return *this;

size = rhs.getSize();

delete[] a;
a = new int[size];
for (int i = 0; i < size; i++)
a[i] = rhs.getA()[i];

return *this;
}

int *Case::getA() const
{

return a;
}

int Case::getSize() const
{
return size;
}

Case::~Case()
{

delete[] a;
}

// implement class Dase
Dase::Dase() : b(Base()), c(Case())
{
// delebrately left empty
}

Dase::Dase(int bSize, int barr[2], int cSize, int carr[2])

{
b = Base(bSize, barr);
c = Case(cSize, carr);
}

Dase::Dase(const Dase &dase)
{
b = dase.getB();
c = dase.getC();
}


Dase &Dase::operator=(const Dase &rhs)
{
if (this == &rhs)
return *this;

b = rhs.getB();
c = rhs.getC();

return *this;

}

Base Dase::getB() const
{
return b;
}

Case Dase::getC() const
{
return c;

}

Dase::~Dase()
{
b.~Base();
c.~Case();
}






In the above code, I defined 3 classes: Base, Case, Dase. I included their declarations and implementations. The following is the main code:





#include "classes.h"

int main()
{
int arr[2] = {1, 2};

int brr[2] = {3, 4};

Dase d1(2, arr, 2, brr);
Dase d2;

d2 = d1;
}






This is a very simple main code, but I got "double free or corruption (fasttop)" error in the runtime.



I noticed that when I deleted the destructor in the class Dase, this problem went away. What shall I do to fix this problem if I want to keep the destructor for Dase? Shall I change its implementation?



Thank you!


Answer



You should not call destructors explicitly. It's done automatically.



So, replace




Dase::~Dase()
{
b.~Base();
c.~Case();
}


with




Dase::~Dase()
{
}

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...