Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


#Actualfastcall22

Posted 30 August 2013 - 01:13 PM

Here a leak of one int size will occur?

No.

If so, how would the base class know to call its pointing to deconstructor?

Make the base class destructor virtual.


In C++, it is considered good practice to use a virtual destructor:
class Base {
public:
    virtual ~Base() {
    }

private:
    bool mTest;
};

class Derived : public Base {
public:
    Derived() {
        mData = new int[1000];
    }

    ~Derived() {
        delete[] mData;
    }

private:
    int* mData;
    double mOtherData;
};

int main() {
    Base* p = new Derived;
    delete p;
}
If Base::~Base were not virtual, then Derived::~Derived would not be called, and the memory for its mData would not be released. The members for Derived (the pointer mData, mOtherData, and mTest) would not leak in either case, because the members reside inside the memory block allocated for Derived. Your C++ runtime and operating system keep track of allocated blocks, so the runtime/operating system is smart enough to know the size of a block given only the pointer to its address. You can technically do something like this:
void magic( void* ptr ) {
    // Neither ~Base() or ~Derived() will be called because we won't know what type ptr is!
    // But the memory block will be freed regardless.
    delete ptr;
}

int main() {
    magic( (void*)(new Derived) );
}
Whether it is morally acceptable to do or not is another question...

#1fastcall22

Posted 30 August 2013 - 01:12 PM

In C++, it is considered good practice to use a virtual destructor:
class Base {
public:
    virtual ~Base() {
    }

private:
    bool mTest;
};

class Derived : public Base {
public:
    Derived() {
        mData = new int[1000];
    }

    ~Derived() {
        delete[] mData;
    }

private:
    int* mData;
    double mOtherData;
};

int main() {
    Base* p = new Derived;
    delete p;
}
If Base::~Base were not virtual, then Derived::~Derived would not be called, and the memory for its mData would not be released. The members for Derived (the pointer mData, mOtherData, and mTest) would not leak in either case, because the members reside inside the memory block allocated for Derived. Your C++ runtime and operating system keep track of allocated blocks, so the runtime/operating system is smart enough to know the size of a block given only the pointer to its address. You can technically do something like this:
void magic( void* ptr ) {
    // Neither ~Base() or ~Derived() will be called because we won't know what type ptr is!
    // But the memory block will be freed regardless.
    delete ptr;
}

int main() {
    magic( (void*)(new Derived) );
}
Whether it is morally acceptable to do or not is another question...

PARTNERS