|
|
Show more code! Make sure we can see the "<" and ">" characters and what's between them in your post: it's obviously essential information when dealing with templates.
Steve
|
|
|
|
|
Do you have email I will send you the code? It's vc6 WIN32 + STL (no MFC)
|
|
|
|
|
Try the page heap suggestion below. I'm happy to give advice but I haven't got the time presently to do it for you; sorry.
Steve
|
|
|
|
|
|
Stephen, look at his code and there is the reason!
http://www.codeproject.com/script/comments/forums.asp?msg=2182788&forumid=1647#xx2182788xx
Maxwell Chen
|
|
|
|
|
|
I'd guess you've corrupted the heap at another location in your program and the problem in manifesting here. Try the following:
I give the following advice about once a month; it often helps me track down the nastier heap errors:
Try enabling the page heap[^] for your process. Follow these steps:
1. Download and install WinDBG[^].
2. Select “Start”->“All Programs”->“Debugging Tools for Windows”->“Global Flags”.
3. Select the “Image File” tab.
4. In the “Image: (TAB to refresh)” edit control enter the name of your app then press TAB. Just the name with the extension; not the full path.
5. Tick the following:
- “Enable page heap”
- “Enable heap tail checking”
- “Enable heap free checking”
- “Enable heap parameter checking”
- “Enable heap validation on call”
- “Create user mode stack trace database”
6. Press “Apply”.
7. Debug your application. Any debugger will do but with WinDBG you have access to the stack traces of allocations via the !heap –p –a command, for example. When a heap problem is detected a breakpoint will be generated.
8. When done un-tick all the options you ticked, press “Apply” then dismiss GFlags. This step is important as if it’s skipped all applications named as entered in step 4 will run with the page heap enabled.
Note that when using the page heap your application will run much slower than normal and consume way more memory. It’s good to have a beefy machine to do such tests; and such tests should be ran regularly on all applications you develop as part of regular testing activities. If I find a part of my application that’s too slow with the page heap enabled I optimize the memory allocation in that region.
Steve
|
|
|
|
|
Stephen Hewitt wrote: I'd guess you've corrupted the heap at another location in your program and the problem in manifesting here. Try the following:
That's every programmer's nightmare - but I think I will check more carefully where memory is allocated, free and used...
Thanks very much that's very detail...
It turns out I already have WinDBG installed just never used it...
|
|
|
|
|
Maxwell has found your mistake: see here[^].
Steve
|
|
|
|
|
Thanks
Originally:
CSomeClass::~CSomeClass()<br />
{<br />
m_oApplicationConfig.clear();<br />
<br />
return;<br />
}
After (it's there because I was trying a couple of things):
CSomeClass::~CSomeClass()<br />
{<br />
m_strConfigFileName.~basic_string(); << Crashed here! <br />
m_oApplicationConfig.clear();<br />
<br />
return;<br />
}<br />
Now:
CSomeClass::~CSomeClass()<br />
{<br />
m_oApplicationConfig.clear();<br />
<br />
return;<br />
}
|
|
|
|
|
devvvy wrote: Now:
CSomeClass::~CSomeClass()
{
m_oApplicationConfig.clear();
return;
}
In this case, you can safely omit the call to clear() : It is done automagically by the multimap-destructor. That idiom is called RAII: "Resource aquisition is initialisation".
Something other smells fishy in your program, and it is not in this class definition.
Do you somewhere have a pointer to a CSomeClass, and delete this twice?
Though I speak with the tongues of men and of angels, and have not money, I am become as a sounding brass, or a tinkling cymbal. George Orwell, "Keep the Aspidistra Flying", Opening words
|
|
|
|
|
It's also one of these things I put there trying to get this working...
removed now... same bug unfortunately...
|
|
|
|
|
devvvy wrote: same bug unfortunately
As I said: This class definition is not the source of the problem - it is the symptom. The tedious page-heap thing may really get this worked out - if you can't find it by hand.
Though I speak with the tongues of men and of angels, and have not money, I am become as a sounding brass, or a tinkling cymbal. George Orwell, "Keep the Aspidistra Flying", Opening words
|
|
|
|
|
I just tried.
I followed steps (1) to (6).
Then I launch application in debugger from Visual Studio 6. The application breaks at:
<br />
_ASSERTE(_CrtIsValidHeapPointer(pUserData));<br />
Stack trace:
_free_dbg_lk(void * 0x018e6fd0, int 1) line 1044 + 48 bytes<br />
_free_dbg(void * 0x018e6fd0, int 1) line 1001 + 13 bytes<br />
free(void * 0x018e6fd0) line 956 + 11 bytes<br />
operator delete(void * 0x018e6fd0) line 7 + 9 bytes<br />
std::allocator<char>::deallocate(void * 0x018e6fd0, unsigned int 33) line 64 + 38 bytes<br />
std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Tidy(unsigned char 1) line 592<br />
std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >() line 59 + 39 bytes<br />
CStartupManager::StartUp(std::basic_string<char,std::char_traits<char>,std::allocator<char> > {0x018e6fd1 "desktop.api.config"}) line 19 + 19 bytes<br />
InitApplication() line 17<br />
main(int 1, char * * 0x0185afb0) line 24<br />
mainCRTStartup() line 206 + 25 bytes<br />
KERNEL32! 7c816fd7()
I'm not sure ... how WinDbg helps to locate the bug (whether it's trying to write to freed memory or ...) ... Should I launch the application from WinDbg instead? By "Open Executable"?
Or should I start the probelm app with Visual Studio 6, but I can't have both VS6 and WinDbg both attached to it right?
Thanks many thanks!!
|
|
|
|
|
devvvy wrote: CStartupManager::StartUp(std::basic_string,std::allocator > {0x018e6fd1 "desktop.api.config"}) line 19 + 19 bytes
InitApplication() line 17
So, InitApplication() is calling CStartupManager::StartUp(). And in line 19 of that class something terrible happened.
Show us that code. Maybe we can spot the error.
Though I speak with the tongues of men and of angels, and have not money, I am become as a sounding brass, or a tinkling cymbal. George Orwell, "Keep the Aspidistra Flying", Opening words
|
|
|
|
|
I have tried your suggestion with WinDbg - guess I know basic operation of WinDbg. But "!analyze -v" seems to be telling me access violation happens in CStartupManager::~StartupManager
<br />
...<br />
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".<br />
BUGCHECK_STR: ACCESS_VIOLATION<br />
...<br />
<br />
STACK_TEXT: <br />
0012fb20 7c968b5e 01741000 018defb0 0012fb48 ntdll!RtlpDphIsNormalHeapBlock+0x81<br />
0012fb40 7c9697ae 00000007 00001002 018defb0 ntdll!RtlpDphNormalHeapValidate+0x2d<br />
0012fb84 7c960a4e 01740000 00000000 018defb0 ntdll!RtlpDebugPageHeapValidate+0x5a<br />
0012fbe8 7c85e9cf 01740000 00000000 018defb0 ntdll!RtlValidateHeap+0x36<br />
0012fbfc 1002ed00 01740000 00000000 018defb0 kernel32!HeapValidate+0x14<br />
0012fc20 1002e051 018defd0 0012fce8 0012fe14 Utilities!_CrtIsValidHeapPointer+0x120 [dbgheap.c @ 1697]<br />
0012fc3c 1002df81 018defd0 00000001 0012fce8 Utilities!_free_dbg_lk+0xa1 [dbgheap.c @ 1044]<br />
0012fc70 1002df0e 018defd0 00000001 0012fc8c Utilities!_free_dbg+0x41 [dbgheap.c @ 1001]<br />
0012fc80 1001605c 018defd0 0012fce8 100038b6 Utilities!free+0xe [dbgheap.c @ 956]<br />
0012fc8c 100038b6 018defd0 0012fd4c 0012fe14 Utilities!operator delete+0xc [delop.cpp @ 7]<br />
0012fce8 100030d2 018defd0 00000021 0012fda8 Utilities!std::allocator<char>::deallocate+0x26 [c:\program files\microsoft visual studio\vc98\include\xmemory @ 64]<br />
0012fd4c 100029b7 00000001 0012fe00 0012fe14 Utilities!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Tidy+0x82 [c:\program files\microsoft visual studio\vc98\include\xstring @ 592]<br />
0012fda8 10006571 0012ff20 0012fe14 7ffd9000 Utilities!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >+0x27 [c:\program files\microsoft visual studio\vc98\include\xstring @ 59]<br />
0012fe0c 00402912 0012ff80 00d2f778 7ffd9000 Utilities!CStartupManager::~CStartupManager+0x71 [C:\...path...\Utilities\StartupManager.cpp @ 15]<br />
0012ff2c 0040298d 00d2f6f2 00d2f778 7ffd9000 DesktopAPI!InitApplication+0x92 [C:\...path...\DesktopAPI.cpp @ 17]<br />
0012ff80 00404849 00000001 0185afb0 0185cf50 DesktopAPI!main+0x1d <br />
[C:\...path...\DesktopAPI.cpp @ 24]<br />
0012ffc0 7c816fd7 00d2f6f2 00d2f778 7ffd9000 DesktopAPI!mainCRTStartup+0xe9 [crt0.c @ 206]<br />
0012fff0 00000000 00404760 00000000 78746341 kernel32!BaseProcessStart+0x23<br />
It seems to indicate that the fault isn't catched instantly -- how can I enable "Full-page heap" from Global Flags?
While WinDbg indicates this happens in destructor CStartupManager::~CStartupManager ... seems like it's actually happenning before that.
Reference here:
Full-Page Heap
Full-page heap should be enabled for individual processes, or under limited parameters for large processes, because of its high memory requirements. It cannot be enabled system-wide, because it is difficult to evaluate the required page file size. Using a page file that is too small with system-wide full-page heap renders the system unbootable.
The advantage of full-page heap is that it causes a process to access violate (AV) exactly at the point of failure. This makes the failure easy to debug. In order to be able to pinpoint failures, first use normal page heap to determine the range where a process is failing, and then use full-page heap on individual large-scale processes for that restricted class of allocations (that is, a specific size range or a specific library).
Normal Page Heap
Normal page heap can be used for the testing of large-scale processes without the high memory consumption that full-page heap requires. However, normal page heap delays detection until blocks are freed, thus making failures more difficult to debug.
In general, use normal page heap for initial large-scale processes testing. Then, if problems are detected, enable full-page heap for a restricted class of allocations in those processes.
|
|
|
|
|
devvvy wrote: What should I do in destructor?
Nothing special. When they go out of scope, the destructors for the string , ifstream , and multimap objects will do their own cleanup.
devvvy wrote: CSomeClass::~CSomeClass() line 16 + 51 bytes
What does CSomeClass destructor look like?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
what about "Objects" in a multimap? Do I need to call destructor for these and free(obj) before?
Suppose that I have:
map<string, csomeobject*=""> oMap;
do I need to do this:
<br />
for(iter=oMap.begin(); iter!=oMap.end(); iter++)<br />
{<br />
strKey = iter.first;<br />
strKey.clear();<br />
<br />
*pObj = iter.second;<br />
free(pObj);<br />
pObj=NULL;<br />
}
|
|
|
|
|
Hi
I am trying to understand serialization in MFC. In every document it says:
"Serialization is the process of writing or reading an object to or from a persistent storage medium such as a disk file."
I don't understand what type of file it is written. What is its extension?
Where do we declare file object that we will use?
Thanks.
|
|
|
|
|
When you create the CArchive object for serialization, you provide a CFile object.
It's up to you to provide the type of file you want. It doesn't necessarily have
to be a disk file. You can use a CMemFile or any custom CFile-derived class object.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you.
But I do not understand here. For doc class:
void CCodeDoc::Serialize(CArchive& ar)<br />
{<br />
if (ar.IsStoring())<br />
{<br />
}<br />
else<br />
{<br />
}<br />
}
And this is called from Framework. So I do not create any CArchieve file. Carchieve file created by Framework.
I tried to serialize "int x" and closed application. But there is no extra file in project's directory. So where is the file? What type of file is created by framework?
I hope i can explain my problem.
Thanks again.
|
|
|
|
|
How did you try this? Default CDocument serialization is done in response
to the ID_FILE_SAVE/ID_FILE_SAVE_AS commands, where you are prompted
for a pathname to save to.
Some links in case you haven't seen them yet...
Two Ways to Create a CArchive Object[^]
Serialization in MFC[^]
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hmm
OK.
Now I understand my fault.
Thank you.
|
|
|
|
|
When you create your Win32 application, there is a step in the assistant where you can specify the extension for fyles, the filter for explorer and some more of the programm you are creating. These will be used around all your default behaviours. But it is still possible to open/read/write files wih different extension than your programm. But this is better to be used with CFile than with serialize (at least, it was easier for me)
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|