[C++] Delete base class pointer which actually holds a derived class pointer?

Started by
10 comments, last by ToohrVyk 15 years, 8 months ago
Is this perfectly safe?

#include <iostream>

class CBase {};
class CDerived : public CBase {};

int main ()
{
    CBase* b = new CDerived;
    delete b;
    return 0;
}

I have an array of base pointers, which is filled with derived pointers of that base class. Is it safe to delete it? Should I cast it first to the derived class (how do I know which class I have filled it with? ^^). Unsure if it's safe, how would it know the size it has to deallocate? I still wonder how you can ever fill a base class pointer with a derived class pointer, they both differ in size, don't they? Thanks.
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Advertisement
As long as your base class has a virtual destructor, this is fine.

Quote:
I still wonder how you can ever fill a base class pointer with a derived class pointer, they both differ in size, don't they?


A derived class is a base class. And you don't "fill" a pointer with an object, you point at an object with a pointer.
Yea as far as I know the code is fine. You do not need to cast it, but the base class should have a virtual destructor.

Each compiler has it's own mechanism for determining what the size is. Don't worry about it !!

EDIT : damn .. to slow !!
Hehe, thanks guys :), so it's done at compiler time, not run time, thanks :)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by Decrius
so it's done at compiler time, not run time


What's done at compile time? Virtual dispatches are done at run-time.
To see how making the destructor virtual makes a difference you might try this:

#include <iostream>using std::cout;struct A{    A() { cout << "A()\n"; }    //virtual    ~A() { cout << "~A()\n"; }};struct B: public A{    B() { cout << "B()\n"; }    ~B() { cout << "~B()\n"; }};int main(){    A* p = new B;    delete p;}


The B part of the object is never destructed and that's undefined behaviour.

Now comment in the virtual keyword. Now at run-time the destructor for both parts of *p are called, as the virtual keyword tells it to start destructing from the actual most derived type of *p and call all the destructors all the way up to that of the parent.
So, a virtual is usefull for when you have a base class pointer filled with a derived class pointer?

As for the compiler-time, I referred to the sizes of what should be deallocated ;)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by Decrius
So, a virtual is usefull for when you have a base class pointer filled with a derived class pointer?

As for the compiler-time, I referred to the sizes of what should be deallocated ;)


Once again, as Driv3MeFar already pointed out, you don't "fill" pointers. You allocate memory somewhere and the pointer points to the address in memory where that section begins.
Best regards, Omid
A pointer is data aswell. You get what I mean, that's most important ;)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
The problem isn't that he gets what you mean. The concern is that you may not quite understand what you're saying. They're trying to help. :)

If you "fill" a pointer with a value, then you would be treating the pointer as some form of data structure - a way to store various bits of information in memory in different ways.

What you need to understand is you're not actually "filling" the pointer. What you have is a pointer that contains a value, much like an integer or float contains a value. And, just like an integer, a pointer takes up a few bytes in memory (size varies based on your architecture, 16-bit, 32-bit, 64-bit, or whatever). These few bytes are only used to store a memory address. That's it, nothing else. This memory address is located completely separate of the pointer, at some random location in memory and you don't care where.

Quote:
As for the compiler-time, I referred to the sizes of what should be deallocated ;)


Again, no. Virtual functions are handled at run-time. As are allocations and deallocations. Consider:

#include <iostream>using namespace std;class A{public:   A() { cout << "A()" << endl; }   virtual ~A() { cout << "~A()" << endl; }private:};class B : public A{public:   B() { cout << "B()" << endl; }   ~B() { cout << "~B()" << endl; }private:};int main(){   char input;   A* obj;   cout << "Enter 1 or 2: ";   cin >> input;      if ( input == '1' )  { obj = new A; }   else { obj = new B; }   delete obj;   return 0;}


You can enter 1 or 2. At compile time, the code doesn't know which variable obj will be allocated to when it calls delete. Nor does it care. It's handled at run time. This is even the case if you don't use virtual methods. However, to ensure your destructor is run for your derived class (and any other methods you may choose to override in the derived class that are in the base class), you need to be virtual.

This topic is closed to new replies.

Advertisement