destructors and heritance

Hi everyone!
I try to delete a derived_class-object using a base_class-pointer. i read that i need a virtual destructor to do this properly but it doesnt seem to work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class base
{
    public:
    int x;
    base(){x=1;};
    virtual ~base(){};
};

class derived :public base
{
    public:
    int y;
    derived(){y=2;};
    ~derived(){};
};


int main()
{
    base* test = new derived();
    cout << test->x<<"\n";
    delete test;
    cout << test->x<<"\n";
    return 0;
}


it seems the object still exists after calling delete since "1" is printed to the screen twice.
What am i doing wrong? do i have to add something to the destructor?

interestingly it works when i dont manually declare the destructors...but i was told this causes memory leaks...
any ideas?
Last edited on
It is working as intended. When you delete a pointer, the memory is freed, but the pointer is still pointing at that area. You have just gotten lucky and the memory still happened to exist inside your programs memory so you didn't get a segfault.

And as for your second statement, yes, it does cause memory leaks because only the base destructor would be called in that instance, meaning derived class resources won't be freed.
I see...so since my method didnt work is there any possibility to check whether the delete was successful?
~derived(){ std::cout << "derived\n"; };
~derived(){ std::cout << "derived\n"; };


that way ill know whether the destructor has been called but i wont know whether the destructor deleted the object properly...do i just have to rely on the destructor working correctly?
The same way that you tell if any code is working correctly. The destructor is a function after all and it does what you tell it to.

Will delete free the memory? I think you have to take that as a 'given' as long as you call it on a valid pointer.
Simple! Try to compare adresses of sequentially allocated objects.

Equal here:

1
2
3
4
5
6
7
8
9
10
11
base* test1;
base* test2;

  test1 = new derived();
  cout << test1 << endl;
  delete test1;

  test2 = new derived();
  cout << test2 << endl;
  delete test2;


Not equal here:

1
2
3
4
5
6
7
8
9
10
11
12
base* test1;
base* test2;

  test1 = new derived();
  cout << test1 << endl;
  
  test2 = new derived();
  cout << test2 << endl;

  delete test1;
  delete test2;
boolivar wrote:
Simple! Try to compare adresses of sequentially allocated objects.


I honestly don't think you can rely on that.
delete does two things. First, it runs the body of the destructors, starting with the most derived class and
working towards the base. Second, it frees the memory that was allocated to the object on the
corresponding new.

new and delete work. If you give delete a pointer allocated by new, then delete works. If you give
delete a bad pointer, then delete will do nothing good, but it's your programming error.

The language makes no guarantees obviously regarding the correctness of the body of the destructors
since they are provided by the programmer.
Galik, where is my mistake?
You are assuming that the free-store will allocate the same chunk of memory back to you that you just deleted. That's not guaranteed.
Galik, yes is not necessary but sufficient.
With VS2008 and gcc 3.4.5 it works!
I am sure it works in some implementations. But it could change with a different version of gcc, for example. Also the new and delete operators can be overloaded to behave differently.

So even if the default new and delete work on your current compiler version, there is no saying that the same compiler version will give the same result in two different parts of the same project.
Last edited on
Topic archived. No new replies allowed.