The code leading to this memory corruption has been reduced to
CWrkshtImageView* temp = new
CWrkshtImageView(IDC_RESULTIMG,hwndDlg,CurOpID,this,true,false);
CString text;
for(int i=0;i<7;i++)
{
text.Format("%4d pixels",i);
text.Format("%5d pixels",i);
text.Format("%6d pixels",i);
text.Format("%7d pixels",i);
text.Format("%8d pixels",i);
text.Format("%9d pixels",i);
text.Format("%10d pixels",i);
text.Format("%11d pixels",i);
}
With the memory corruption occuring during the first pass of the loop.
The text.Format uses the memory of the previously created class instance temp.
I see no errors in your code, except from the fact that you did not use _T()
decorator for CString.Format string. Your code will compile in ANSI/MBCS,
but I think it will not compile in Unicode builds.
I tried reproducing the for loop with VS2008 (adding _T() decorator) and I
got no error.
It might be that there is a problem in CWrkshtImageView constructor?
I would suggest you to debug step-by-step in aforementioned class
constructor.
Giovanni
"Giovanni Dicanio" wrote:
The constructor works fine, previously the memory corruption occured when
ON_UPDATE_COMMAND_UI fired after this function had completed and called
CString.Format in a completely other section of the application. The call
was just pushed up into this function to ensure the error is being caused by
this call. If I step through the function, the memory of the class is
corrupted in the second or third call to Format(...). (Basicly the entire
memory of the object is overwritten with the new string).
This only occurs in the release build.
Please don't can't claim there's a problem with certain functionality
if you don't have a test case that others can verify.
Try simulating your problem in clean-slate code - 2c here says you
can't do it.
IOW... You are mistaken, there's no problem with CString::Format.
There is something else and you are poorly diagnosing the problem.
Goran.
The code below cannot cause memory corruption. However, if your heap is already damaged,
the numerous allocations/deallocations required to implement this loop (and you said "the
first pass", which is meaningless; you did not identify the actual statement that did the
overwrite, nor give us addresses involved, making diagnosis nearly impossible). I would
suggest sprinkling
ASSERT(_heapchk() == _HEAPOK);
statements around in the code below as a start.
If one of these triggers, it means you had pre-existing damage, and thus attributing it to
the CString::Format is erroneous. I suspect that if there were such a bug in
CString::Format that it would have been detected and fixed long before this. But a
corrupted heap makes everything possible.
Essentially, put the ASSERT in before this code starts and after every statement that can
touch the heap. Which is pretty much every statement.
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
On Mon, 15 Jun 2009 05:18:01 -0700, H. Arlinghaus <HArli...@discussions.microsoft.com>
wrote:
****
I'm curious. Since this only happens in the release build, WHY DIDN'T YOU SAY THAT????
Exactly what part of "please give all critical information in a bug report" did you miss?
I'm not sure if _heapchk() actually does anything in the release build, but it makes it
even more likely that you are seeing memory damage that has preexisted. But try it
anyway. I also note that you do not provide any information as to which version of VS,
including service pack, you were using. Note that ethereal vibrations are not a valid
means of doing software diagnosis.
joe
"Goran" wrote:
I dont doubt it won't happen in a new project, and if I did know how to
recreate the bug it would be fixed.
If you have suggestions for what is causing this behavior I would be glad to
hear them. The most likely possibility is that the memory reallocation done
by .Format() is allocating the memory in use by the class a second time,
however I do not know what could be causing this. Replacing the calls with
sprintf works, however the next time .Format() is called in the application
the same issue occurs. I also tried having a loop first allocating 1000
randonly sized chunks of memory and then freeing these between the class
instantiation and the call to Format(), this also works, but it most likely
does not prevent the issue outright.
See my earlier response.
joe
On Mon, 15 Jun 2009 09:19:27 -0700, H. Arlinghaus <HArli...@discussions.microsoft.com>
wrote:
>
>
( Sorry if I sounded as an ass, I am working on my Newcomer
impression ;-) )
The most likely cause for all behavior of the sort is broken memory.
You managed to overwrite something, and by the look of things,
candidate no 1 is heap. (If you see "inexplicable" crashes or program
code ending up in non-existing places, then likely cause is broken
stack).
> The most likely possibility is that the memory reallocation done
> by .Format() is allocating the memory in use by the class a second time,
> however I do not know what could be causing this.
No, that is not possible without heap being __already broken__.
I am only this because you really should get your eyes off ::Format.
It's only a visible consequence of a bug elsewhere.You have been told
that already, please trust us ;-) .
As for what to do... There's no easy way out. You should look
immediately into all allocations you do yourself and meticulously
check bounds when accessing this memory. Make sure that you know
exactly where each of these pointers is stored and that there's no
pointees once block is freed. Try removing parts of code (or not
running it) until you see no problem. Then gradually put stuff back in
until bug re-appears. Run your code under the debugger - a lot, and
check that you have no assertions while doing it and that there's no
messages or debug breaks from the system coming to the debugger.
You must find your bug(s). Internet doesn't know your code, there's
little chance it could help ;-).
HTH,
Goran.
My first guesses would be either a double deleted pointer or continued use
of a pointer after deletion. For example:
// double delete problem
XX* px = new XX();
// Use px...
delete px;
delete px; // Uh oh
// Using a pointer after deletion
XX* px = new XX();
// Use px...
delete px;
px->DoSomething(); // Uh oh
I always make it a habit of setting deleted pointers to NULL following the
delete statement (if memory allocation/deallocation is involved). This
solves the above two problems and a number of others. For example:
XX* px = new XX();
// Use px...
delete px;
px = NULL;
// Any further use of px (including another delete) will be handled
correctly
In your case, the pointer problem will be in code preceding (time-wise not
necessarily source listing-wise) the code that you posted.
Note that I said that this is my first guess. The problem might still be
something else...
"H. Arlinghaus" <H. Arlin...@discussions.microsoft.com> wrote in message
news:EE5AEB8F-4A04-4E7F...@microsoft.com...
> ( Sorry if I sounded as an ass, I am working on my Newcomer
> impression ;-) )
>
I tried the count to 10 rule, it helps :)
> The most likely cause for all behavior of the sort is broken memory.
> You managed to overwrite something, and by the look of things,
> candidate no 1 is heap. (If you see "inexplicable" crashes or program
> code ending up in non-existing places, then likely cause is broken
> stack).
>
>
> No, that is not possible without heap being __already broken__.
>
> I am only this because you really should get your eyes off ::Format.
> It's only a visible consequence of a bug elsewhere.You have been told
> that already, please trust us ;-) .
>
> As for what to do... There's no easy way out. You should look
> immediately into all allocations you do yourself and meticulously
> check bounds when accessing this memory. Make sure that you know
> exactly where each of these pointers is stored and that there's no
> pointees once block is freed. Try removing parts of code (or not
> running it) until you see no problem. Then gradually put stuff back in
> until bug re-appears. Run your code under the debugger - a lot, and
> check that you have no assertions while doing it and that there's no
> messages or debug breaks from the system coming to the debugger.
>
> You must find your bug(s). Internet doesn't know your code, there's
> little chance it could help ;-).
>
> HTH,
> Goran.
>
I tried verifyingthe heap using gflags, however the second I enabled any
heap checking option in gflags for my application the bug went away, yet
gflags does not report an error. Wouldn't this pretty much rule out the heap?
(also, ASSERT(_heapchk() == _HEAPOK); does not seem to run in release
builds, or my attempt at manually corrupting the heap to test it only worked
in the debug build. Without my deliberate memory corruption in the debug
build the assert also never triggered.)
-Henrik
>"Goran" wrote:
****
If you cared about the kernel heap, you would use GFLAGS. You do not, so it doesn't do
you any good.
****
>
>(also, ASSERT(_heapchk() == _HEAPOK); does not seem to run in release
>builds, or my attempt at manually corrupting the heap to test it only worked
>in the debug build. Without my deliberate memory corruption in the debug
>build the assert also never triggered.)
****
The ASSERT, of course, will not work, for the obvious reasons. You probably have to
replace it with
#define CHECKHEAP if(_heapchk() != _HEAPOK) DebugBreakPoint()
If this doesn't work because _heapchk() itself has gone away in release mode, try the
HeapChk API, which is some help.
joe
****
>
>-Henrik
Or it could be possible to use modern C++ smart pointer classes like
shared_ptr or scoped_ptr (basing on particular context and needs), instead
of raw pointers.
(Smart pointers have the advantage of being exception-safe as well.)
Giovanni