jwilcox
asked on
CFileFind is evil
Hi:
I have a program and for some reason whenever I run this code snippet I get an assertion failure in afx.inl at line 118. I've tried this as both *.* and *.bmp, which *.bmp files exist in that directory! I have m_PicData declared in my classes definition as
CFileFind m_PicData;
Here is the actual code that is giving the error:
m_PicData.FindFile("C:\\Ca mi\\Christ mas\\Image s\\*.*", 0);
m_PicData.FindNextFile();
Thank you,
I have a program and for some reason whenever I run this code snippet I get an assertion failure in afx.inl at line 118. I've tried this as both *.* and *.bmp, which *.bmp files exist in that directory! I have m_PicData declared in my classes definition as
CFileFind m_PicData;
Here is the actual code that is giving the error:
m_PicData.FindFile("C:\\Ca
m_PicData.FindNextFile();
Thank you,
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Which version of Visual C++ are you using? What exactly is the assertion failure?
ASKER
It is the FindFile line that is crashing, have any wisdom as to why that would be the problem? I am using Visual C++ 5.0.
Thanks,
Thanks,
ASKER
Actually, do you think that it might be that I'm specifically assigning a value for the dwUnused? I should probably jsut not touch that, huh?
CFileFind isn't evil. I wrote the class myself, and I'm not an evil person.
I have VC++ 6.0 without any SP's. There's no ASSERT() on line 118 of AFX.INL.
Which version of VC++ are you using? Which SP's do you have installed? What's the stack trace on the way to
the assertion?
Why aren't you checking the return value from FindFile()? If it returns FALSE, the CFileFind() object is invalid and no operations can be performed on it. In a debug build, that would cause ASSERT_VALID() to trigger.
..B ekiM
I have VC++ 6.0 without any SP's. There's no ASSERT() on line 118 of AFX.INL.
Which version of VC++ are you using? Which SP's do you have installed? What's the stack trace on the way to
the assertion?
Why aren't you checking the return value from FindFile()? If it returns FALSE, the CFileFind() object is invalid and no operations can be performed on it. In a debug build, that would cause ASSERT_VALID() to trigger.
..B ekiM
ASKER
Mike:
See my above comment, I'm using Visual C++ 5.0, and it appears that it is dying on the actual FindFile line, and never even gets to the FindNextFile. In my real program I do check the return value,I just put that in as a really quick snippet.
I didn't mean to offend with the whole CFileFind is evil title, just used it for lack of better wording. BTW, I love your MFC book for Visual C++ 5.0
See my above comment, I'm using Visual C++ 5.0, and it appears that it is dying on the actual FindFile line, and never even gets to the FindNextFile. In my real program I do check the return value,I just put that in as a really quick snippet.
I didn't mean to offend with the whole CFileFind is evil title, just used it for lack of better wording. BTW, I love your MFC book for Visual C++ 5.0
> I get an assertion failure in afx.inl at line 118.
In Visual C++ 5.0, that line implies that someone's calling CString::GetData() on a corrupt CString.
The code you've posted doesn't seem to use CString for anything.
In that same codebase, CFileFind::FindNextFile() will only ASSERT if FindFile() wasn't called, or the call to it failed. It doesn't use CString.
> In my real program I do check the return value
You're giving us lots of conflicting symptoms, and that makes it hard to make a diagnosis. Especially without seeing the code that you're actually using, or a stack trace leading to the assertion that you're complaining about. Please post the code you're really using; that would help immensely. Providing a stack trace seems like it's even more important.
> I didn't mean to offend with the whole CFileFind is evil title,
> just used it for lack of better wording.
It shocks me how people so often forget that there are almost always hard-working, concientious people behind the software they're using.
> BTW, I love your MFC book for Visual C++ 5.0
Thank you.
..B ekiM
In Visual C++ 5.0, that line implies that someone's calling CString::GetData() on a corrupt CString.
The code you've posted doesn't seem to use CString for anything.
In that same codebase, CFileFind::FindNextFile() will only ASSERT if FindFile() wasn't called, or the call to it failed. It doesn't use CString.
> In my real program I do check the return value
You're giving us lots of conflicting symptoms, and that makes it hard to make a diagnosis. Especially without seeing the code that you're actually using, or a stack trace leading to the assertion that you're complaining about. Please post the code you're really using; that would help immensely. Providing a stack trace seems like it's even more important.
> I didn't mean to offend with the whole CFileFind is evil title,
> just used it for lack of better wording.
It shocks me how people so often forget that there are almost always hard-working, concientious people behind the software they're using.
> BTW, I love your MFC book for Visual C++ 5.0
Thank you.
..B ekiM
ASKER
Okay here is the exact method all of this is happening in, along with its call stack, I hpe this helps you. I really do appreciate all the effort you're putting into this, for me.
CDrawWnd::CDrawWnd(BOOL bAutoDelete)
{
m_bAutoDelete = bAutoDelete;
m_nPos = 0;
m_nStep = 1;
m_rgnLast.CreateRectRgn(0, 0,0,0);
m_CamiImage = new CBitmap();
BOOL IsPics = m_PicData.FindFile("C:\\Ca mi\\Christ mas\\Image s\\*.*");
if(IsPics == TRUE)
{
m_PicData.FindNextFile();
}
}
CString::GetData() line 118 + 34 bytes
CString::GetBuffer(int 260) line 416 + 8 bytes
CString::GetBufferSetLengt h(int 260) line 452
CFileFind::FindFile(char * 0x00407648, unsigned long 0) line 82 + 16 bytes
CDrawWnd::CDrawWnd(int 1) line 26 + 22 bytes
CSaverWnd::CSaverWnd() line 18 + 40 bytes
CSaverApp::InitInstance() line 79 + 34 bytes
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x8171d0b4, int 1) line 40 + 11 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x8171d0b4, int 1) line 34
WinMainCRTStartup() line 330 + 55 bytes
KERNEL32! bff8b537()
KERNEL32! bff8b3e9()
KERNEL32! bff89dac()
Thank you!
CDrawWnd::CDrawWnd(BOOL bAutoDelete)
{
m_bAutoDelete = bAutoDelete;
m_nPos = 0;
m_nStep = 1;
m_rgnLast.CreateRectRgn(0,
m_CamiImage = new CBitmap();
BOOL IsPics = m_PicData.FindFile("C:\\Ca
if(IsPics == TRUE)
{
m_PicData.FindNextFile();
}
}
CString::GetData() line 118 + 34 bytes
CString::GetBuffer(int 260) line 416 + 8 bytes
CString::GetBufferSetLengt
CFileFind::FindFile(char * 0x00407648, unsigned long 0) line 82 + 16 bytes
CDrawWnd::CDrawWnd(int 1) line 26 + 22 bytes
CSaverWnd::CSaverWnd() line 18 + 40 bytes
CSaverApp::InitInstance() line 79 + 34 bytes
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x8171d0b4, int 1) line 40 + 11 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x8171d0b4, int 1) line 34
WinMainCRTStartup() line 330 + 55 bytes
KERNEL32! bff8b537()
KERNEL32! bff8b3e9()
KERNEL32! bff89dac()
Thank you!
Unfortuantely, I don't have the luxury of having VC++ 5.0 setup at home at this time. Your problem doesn't repro for me under VC++ 6.0.
You're constructing a CDrawWnd object, and presumably m_PicData is a CFileFind member of that class, right? Is it a regular member, or a static member? (Or is it coming from somewhere else?)
Assuming it's a regular member: by the time the CDrawWnd constructor is called, the CFileFind member at m_PicData should be fully constructed. And in that construction, CFileFind should construct its CString m_strRoot member.
That CString construction should be initalizing m_PicData.m_strRoot.m_pchD ata to point at an identity empty string MFC uses instead of NULL. But that doesn't appear to be happening in your code.
Either my assumption about the scope of m_PicData is wrong, or there's something very wierd happening in your CDrawWnd constructor that's causing the m_pchData CString is about to use to be improperly initialized.
You should try putting a breakpoint on CFileFind::CFileFind to see if it's being called. On the opening curly brace of CFileFind's constructor, you should be able to trace into (that is, use F11) to watch the CFileFind constructor get its CString member data built. That should lead you to seeing CString::Init() being called to set m_pchData to afxEmptyString.m_pchData.
If it does happen, then you need to figure out how the m_pchData is getting reset to zero. If it doesn't happen, you need to figure out why.
..B ekiM
You're constructing a CDrawWnd object, and presumably m_PicData is a CFileFind member of that class, right? Is it a regular member, or a static member? (Or is it coming from somewhere else?)
Assuming it's a regular member: by the time the CDrawWnd constructor is called, the CFileFind member at m_PicData should be fully constructed. And in that construction, CFileFind should construct its CString m_strRoot member.
That CString construction should be initalizing m_PicData.m_strRoot.m_pchD
Either my assumption about the scope of m_PicData is wrong, or there's something very wierd happening in your CDrawWnd constructor that's causing the m_pchData CString is about to use to be improperly initialized.
You should try putting a breakpoint on CFileFind::CFileFind to see if it's being called. On the opening curly brace of CFileFind's constructor, you should be able to trace into (that is, use F11) to watch the CFileFind constructor get its CString member data built. That should lead you to seeing CString::Init() being called to set m_pchData to afxEmptyString.m_pchData.
If it does happen, then you need to figure out how the m_pchData is getting reset to zero. If it doesn't happen, you need to figure out why.
..B ekiM
ASKER
Well, by moving both FindFile and FindNextFile out of the constructor that mayhem seems to have ceased.
Now, however, for some odd reason, my initial call to FindFile returns TRUE, my subsequent call to FindNextFile returns true. calling GetFilePath() returns "".
Both m_strRoot and m_pchData are "" also.. any clue why both of those calls are returning values saying they supposedly found something, but yet don't allow GetFilePath to behave correctly?
Thank you,
Now, however, for some odd reason, my initial call to FindFile returns TRUE, my subsequent call to FindNextFile returns true. calling GetFilePath() returns "".
Both m_strRoot and m_pchData are "" also.. any clue why both of those calls are returning values saying they supposedly found something, but yet don't allow GetFilePath to behave correctly?
Thank you,
> Well, by moving both FindFile and FindNextFile out of the
> constructor that mayhem seems to have ceased.
It shouldn't matter. That it does suggests something else is really screwed-up about your application.
> Both m_strRoot and m_pchData are "" also.. any clue why both
> of those calls are returning values saying they supposedly
> found something, but yet don't allow GetFilePath
> to behave correctly?
Nope. You can trace right into the code to see what's going on, and I'm not sure I understand why you haven't done that.
..B ekiM
ASKER
I'm sure that your answer works great, but I can't get it to work for me. Thank you everyone for all your efforts however!