Link to home
Start Free TrialLog in
Avatar of jwilcox
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:\\Cami\\Christmas\\Images\\*.*", 0);
      m_PicData.FindNextFile();

Thank you,
ASKER CERTIFIED SOLUTION
Avatar of bhat
bhat

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Which version of Visual C++ are you using? What exactly is the assertion failure?
Avatar of jwilcox
jwilcox

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,
Avatar of jwilcox

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
Avatar of jwilcox

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
> 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
Avatar of jwilcox

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:\\Cami\\Christmas\\Images\\*.*");
      if(IsPics == TRUE)
      {
            m_PicData.FindNextFile();
      }
}

CString::GetData() line 118 + 34 bytes
CString::GetBuffer(int 260) line 416 + 8 bytes
CString::GetBufferSetLength(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!

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_pchData 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
Avatar of jwilcox

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,

 > 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
Avatar of jwilcox

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!