Re: Heap corruption on call to member function returning string
On Nov 21, 4:49 pm, Woody <ols6...@sbcglobal.net> wrote:
On Nov 17, 1:03 pm, Anders Dalvander <anders.dalvan...@gmail.com>
wrote:
Is the struct mp_real is defined in one DLL and used from another DLL/
EXE?
I was about to ask the exact same question until I saw Anders ask it
first.
This is why I posted to this group, where there are many people far
more knowledgeable in C++ than I, and I have received some valuable
advice. If I still cannot solve the problem, I may yet post a
complete, compilable example, but I prefer to reason about it and
avoid the work.
Anyone know of tools that would help?
This sounds like the classic DLL/EXE heap mismatch problem. See:
http://preview.tinyurl.com/39w7v38
In a nutshell:
A DLL is a nicely packed, fully-formed executable module. The calls to
operator new() and operator delete () in such DLL's know exactly where
to new() and delete() their memory from: a heap that is tracked by a
global variable that is inside the DLL.
Conversely,
An EXE is a nicely packed, fully-formed executable module. The
operator calls to new() and operator delete () in such DLL's know
exactly where to new() and delete() their memory from: a heap that is
tracked by a global variable that is inside the EXE.
When you return a string object from a function whose CPU instructions
exist inside the DLL, the invocation of operator new() for any
dynamically-allocated memory for the string will be a result of
executing instructions that are entirely within the DLL. And since it
is conceivable that someone might email you a DLL, the DLL must know,
entirely in advance, where the new()'ed memory will come from,
specifically that is, when it instructions are executed. If it always
came from the OS kernel, on each call to new(), there would be no heap
mismatch problem, but as you know, it doesn't. Instead, a single call
is made to the kernel to grab a large chunk, and from this large
chunk, many smaller chunks are given for each call to operator new().
A global variable that exists inside the DLL is used to keep track of
the current state of allocation of small chunks.
So the delete() in the EXE is looking at the equivalent global
variable for ~its~ large chunk, and of course, this global variable
exists entirely within the image of the EXE, and that is where they
get confused.
Two executable modules; and therefore, two global variables, two
heaps, two new()'s, and two delete()'s.
A simple trick to solve the heap mismatch problem is give problematic C
++ classes virtual destructors.
See:
http://preview.tinyurl.com/39w7v38
I have had endless arguments [over a period of 12 years now] with
other programmers a about:
(1) whether virtual destructors will actually solve the problem
(2) whether my interpretation of why virtual destructors solve the
problem is correct
Suffice it to say that any compiler writer who is faced with the
challenge of accommodating objects with virtual destructors will
almost always implement the new/free mechanism in a certain way, and
that way is the way that most systems that I know of do it. It is
theoretically conceivable to do it a different way, but any such way
would be computationally wasteful and a bit silly. So by virtue [no
pun intended] of the near-necessity of implementing virtual
destructors a certain way, you get the benefit of solving heap
mismatch as a consequence.
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]