Re: Virtual Destructor - Implication & Specification
On Apr 2, 8:09 am, "Martin Bonner" <martinfro...@yahoo.co.uk> wrote:
On Apr 2, 8:36 am, "Le Chaud Lapin" <jaibudu...@gmail.com> wrote:
What "new/delete heap mismatch problem"?
As you know, Windows, like many OS's, have API functions that allow
allocation of N*page_size blocks of memory from the kernel, where N >=
1. From that, the process allocates smaller chunks to satisfy malloc/
free/new/delete. A global variable within the executable helps
determine when the N*page_size allocation has been exhausted and it is
time to go get another allocation from the kernel. Naturally, this
global variable is typically part of the memory allocation library.
In Windows, if one links with a dynamic link library (DLL) where the
memory allocation routines are located, the global variable will be in
the DLL. If one links with a static library where the memory location
routines are located, the global variable will be in the static
library. This means that, if a process always defers memory
allocation to the special, Windows-supplied library for memory
allocation, there will be no problems. But a problem can arise when a
static library has been used in particular situation - an EXE decides
to interact with a DLL that was built by a programmer who decided to
use the static library for memory allocation to build his/her DLL.
This would imply two global variables in use: the one in the EXE, and
the one in the (pre-packaged) DLL.
Making the destructor virtual circumvents this issue because an
invocation of delete against a pointer to polymorphic object will
result in deference to a tilde(~)/free() sequence that is always
appropriate for the actual object pointed to, no matter where it was
created, EXE, or DLL. Without a virtual destructor, this cannot be
said - it would be possible to invoke a tilde(~) or free() against a
pointer to an object that was constructed in a different module (EXE
or DLL).
It sounds as though this is a platform specific issue.
It is...but..this is one of those situations where, in my opinion, not
enough has been said to infer that it is, but enough has been inferred
that, to do it any other way would be awkward at best. I was hoping
that something more has been said in the standard in the last 9 years
when I first noticed this "issue".
The standard is quite clear. Section 5.3.5/3 says:
"In the first alternative (delete object), if the static type of the
operand is different from its dynamic type, the static type shall be a
base class of the operand?s dynamic type and the static type shall
have a virtual
destructor or the behavior is undefined."
In other words, if you have a Base* called p which is actually
pointing at a Derived object, then if you go "delete p;" you have
undefined behaviour unless there is a virtual destructor.
Does this not imply that, if there is a virtual destructor, then the
behavior is defined?
/Your/ problem is that this is not sufficient. The standard does not
define "DLLs" so you can't find any words in the standard that say it
is safe to delete in the Exe an object allocated in a DLL /provided/
the object has a virtual destructor. Microsoft /could/ have chosen to
write their compiler in such a way that there was no way to delete an
object in the exe if it was allocated in the DLL; in fact they didn't,
but you can't use the standard to prove it.
Right. If it is not standard, it is not standard. For my colleagues,
I generally struggle to get them to see that, /if/ making the
destructor virtual "solves" the problems, then it is the presence or
absence of the virtual destructor that "solved" the problem. A bit
circuitous...but this is challenge.
Also, there are two places in TCPPPL 3rd Edition, page 319 and 421/22,
I believe, where it is strongly hinted that the correct size and
destructor (~) for a polymorphic object will be determined by virtue
of the virtual destructor. This, taken along with the fact that a DLL
can be pre-packaged and code-complete before it yields pointers to
polymorphic objects would imply that the code for object deallocation
comes from the DLL.
So I guess what I am saying is that, yes, of course it is
implementation specific, but the combination of what the standard
requires combined with the implementation provides, at least for now,
allows one to infer, at the very minimum, that the _reason_ it works
is because of the virtual destructor.
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]