C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

virtual destructor question

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Stephen Vavasis
Guest





PostPosted: Thu Sep 18, 2003 9:40 am    Post subject: virtual destructor question Reply with quote



In a message posted here last week, I mentioned that a code (not mine)
that I am trying to debug had a destructor that was writing a vfptr
(virtual function jump table pointer) into an object at the wrong
offset. Several people responded that this problem could be caused by
forgetting to declare destructors virtual.

Indeed, when I changed the five classes involved in the hierarchy so
that they all had virtual destructors, the problem went away. So thank
you for that suggestion!

The particular delete statement that was causing the faulty destructor
to execute was an array-delete:
delete[] a_ptr;
This pointer a_ptr was declared to have type A*, and the thing that it
pointed to was really an array of A's, not a derived class. (I think
this matchup of types is required when you use array-delete, but I'm not
sure about that.)

I was under the impression that you need virtual destructors only if you
are deleting an object through a pointer to a base class. Therefore, I
didn't think that virtual destructors would be an issue for the
problem-causing code above. What do all of you think about that?

-- Steve Vavasis

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ben Hutchings
Guest





PostPosted: Fri Sep 19, 2003 9:59 am    Post subject: Re: virtual destructor question Reply with quote



In article <3F68C27C.4977 (AT) cs (DOT) cornell.edu>, Stephen Vavasis wrote:
Quote:
In a message posted here last week, I mentioned that a code (not mine)
that I am trying to debug had a destructor that was writing a vfptr
(virtual function jump table pointer) into an object at the wrong
offset. Several people responded that this problem could be caused by
forgetting to declare destructors virtual.

Indeed, when I changed the five classes involved in the hierarchy so
that they all had virtual destructors, the problem went away. So thank
you for that suggestion!

The particular delete statement that was causing the faulty destructor
to execute was an array-delete:
delete[] a_ptr;
This pointer a_ptr was declared to have type A*, and the thing that it
pointed to was really an array of A's, not a derived class. (I think
this matchup of types is required when you use array-delete, but I'm not
sure about that.)

That is required for *all* array access. All array elements must have
the same type and all arithmetic on pointers into the array must use
pointers to exactly that type (modulo cv-qualifiers).

Quote:
I was under the impression that you need virtual destructors only if you
are deleting an object through a pointer to a base class. Therefore, I
didn't think that virtual destructors would be an issue for the
problem-causing code above. What do all of you think about that?

You are right. It is possible that the bug remains, and your use of a
virtual destructor is just hiding it. Check that the destructor is
actually being called for each element, because there is a bug in VC++
up to version 6.0 that can cause an array deletion to be treated as a
scalar deletion:

<http://support.microsoft.com/default.aspx?scid=kb;en-us;121216>

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Fri Sep 19, 2003 10:10 am    Post subject: Re: virtual destructor question Reply with quote



In article <3F68C27C.4977 (AT) cs (DOT) cornell.edu>, Stephen Vavasis
<vavasis (AT) cs (DOT) cornell.edu> writes
Quote:
I was under the impression that you need virtual destructors only if you
are deleting an object through a pointer to a base class. Therefore, I
didn't think that virtual destructors would be an issue for the
problem-causing code above. What do all of you think about that?

However the code had a dtor that was (attempting) writing a vfptr. That
places the code outside the guarantees of the Standard (a vfptr is an
implementation mechanism). In addition I wonder if the class in question
had any other virtual functions. If it did not then there would not have
been even a conceptual vfptr to play with.

--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ron Natalie
Guest





PostPosted: Fri Sep 19, 2003 10:23 am    Post subject: Re: virtual destructor question Reply with quote


"Stephen Vavasis" <vavasis (AT) cs (DOT) cornell.edu> wrote


Quote:
The particular delete statement that was causing the faulty destructor
to execute was an array-delete:
delete[] a_ptr;
This pointer a_ptr was declared to have type A*, and the thing that it
pointed to was really an array of A's, not a derived class. (I think
this matchup of types is required when you use array-delete, but I'm not
sure about that.)

Yes, you can't have a polymorphic array. The derived to base conversion
is good for only one object, the one the pointer is referring to.

class A { /* ... */ };
class B : public A { /*....*/ };

A* ap = new B[10];

Here the B* value of the new expression is converted to A*. However that
conversion only works for *ap. There are several reasons for this you can
see if you think about it. An obvious one is what happens when sizeof(B) >
sizeof(A). ap{1] wouldn't point to the next object in this case... (there are
other issues with regard to pointer conversion as well).

Quote:
I was under the impression that you need virtual destructors only if you
are deleting an object through a pointer to a base class. Therefore, I
didn't think that virtual destructors would be an issue for the
problem-causing code above. What do all of you think about that?

You are correct. However, the general tenets of good design are that if you
design a class, that others might use, you ought to make it well behaved in
case they decide to do something like polymorphically delete the object.
So you end up with a lot of rules th at are not "strictly required" by the language
but are good design for those following after you.

1. Delete should be virtual if you expect the class to be derived from. (And really
you should almost always expect this, if you have any virtual members at all
the cost of adding the virtual destructor is tiny).
2. Copy construction and assignment should work or be disabled.
etc...

Yoiu might check the "checklist" for class design in Koenig & Moo's Ruminations on
C++ or other C++ design books.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Fri Sep 19, 2003 10:22 pm    Post subject: Re: virtual destructor question Reply with quote

In article <As11PjDcwYa$EwXA (AT) robinton (DOT) demon.co.uk>, Francis Glassborow wrote:
Quote:
In article <3F68C27C.4977 (AT) cs (DOT) cornell.edu>, Stephen Vavasis
[email]vavasis (AT) cs (DOT) cornell.edu[/email]> writes
I was under the impression that you need virtual destructors only if you
are deleting an object through a pointer to a base class. Therefore, I
didn't think that virtual destructors would be an issue for the
problem-causing code above. What do all of you think about that?

However the code had a dtor that was (attempting) writing a vfptr. That
places the code outside the guarantees of the Standard (a vfptr is an
implementation mechanism).
snip


The object code for the destructor was doing that, as it generally must
in an implementation that uses such pointers. The source code was
attempting no such thing.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.