Winapi 在C+;中使用Win32 API进行递归目录遍历时堆栈溢出+;
我一直在试图弄明白为什么这会让我几个小时的堆栈溢出,可能是我刚刚错过的一些简单的东西,它一直在工作,直到我弄糟它,试图清理它。无论如何,一些新鲜的眼睛将不胜感激Winapi 在C+;中使用Win32 API进行递归目录遍历时堆栈溢出+;,winapi,recursion,directory,stack,overflow,Winapi,Recursion,Directory,Stack,Overflow,我一直在试图弄明白为什么这会让我几个小时的堆栈溢出,可能是我刚刚错过的一些简单的东西,它一直在工作,直到我弄糟它,试图清理它。无论如何,一些新鲜的眼睛将不胜感激 int scan(LPSTR szPath, LPSTR pattern) { WIN32_FIND_DATA WFD; HANDLE hSearch; CHAR szFullPath [MAX_PATH+1] = ""; PVOID OldValue = NULL; if( Wow64Disa
int scan(LPSTR szPath, LPSTR pattern) {
WIN32_FIND_DATA WFD;
HANDLE hSearch;
CHAR szFullPath [MAX_PATH+1] = "";
PVOID OldValue = NULL;
if( Wow64DisableWow64FsRedirection(&OldValue) )
{
PathCombine(szFullPath, szPath, "*");
hSearch = FindFirstFile(szFullPath, &WFD);
if ( hSearch != INVALID_HANDLE_VALUE ) {
while(FindNextFile(hSearch,&WFD)) {
if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
FindNextFile(hSearch,&WFD);
}
if(WFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
PathCombine(szFullPath, szPath, WFD.cFileName);
scan(szFullPath, pattern);
}
}
FindClose(hSearch);
}
PathCombine(szFullPath, szPath, pattern);
hSearch = FindFirstFile(szFullPath, &WFD);
if( hSearch != INVALID_HANDLE_VALUE ) {
while( FindNextFile(hSearch, &WFD) ) {
if(!(WFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
PathCombine(szFullPath, szPath, WFD.cFileName);
int index = SendDlgItemMessage(ghWnd, IDLIST, LB_ADDSTRING, 0, (LPARAM)szFullPath);
}
}
FindClose(hSearch);
if ( FALSE == Wow64RevertWow64FsRedirection(OldValue) )
{
return 0;
}
}
return 0;
}
我认为问题在于:
if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
FindNextFile(hSearch,&WFD);
}
添加一个“continue”语句来修复该问题。“.”和“.”的支票是好的。问题是如果它们相邻,代码就会中断
编辑:具体来说,在这个代码块中的FindNextFile之后添加“continue”。我认为问题在于:
if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
FindNextFile(hSearch,&WFD);
}
添加一个“continue”语句来修复该问题。“.”和“.”的支票是好的。问题是如果它们相邻,代码就会中断
编辑:具体来说,在这个代码块中的FindNextFile之后添加“continue”。在您的特定情况下,您可能会意外地在枚举中包含本地目录,从而得到无限递归,然后会再次包含本地目录,等等 但即使您解决了这个问题,也会递归调用
scan
,如果您不十分小心,并且非常了解内存需求、堆栈限制等,这很容易导致堆栈崩溃
如果您解决了无限递归问题,但仍然出现堆栈溢出,通常的解决方案是实现自己的堆栈,而不是依赖递归函数调用
有关堆栈如何工作的详细信息,请参阅。在您的特定情况下,您可能会意外地在枚举中包含本地目录,从而获得无限递归,然后该目录将再次包含本地目录,等等 但即使您解决了这个问题,也会递归调用
scan
,如果您不十分小心,并且非常了解内存需求、堆栈限制等,这很容易导致堆栈崩溃
如果您解决了无限递归问题,但仍然出现堆栈溢出,通常的解决方案是实现自己的堆栈,而不是依赖递归函数调用
有关堆栈如何工作的详细信息,请参阅。在第一个循环中尝试此更改: if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){ continue; } if(strcmp(WFD.cFileName,“…”)| | strcmp(WFD.cFileName,“.”){ 继续; }
在第一个循环中尝试此更改: if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){ continue; } if(strcmp(WFD.cFileName,“…”)| | strcmp(WFD.cFileName,“.”){ 继续; }
这确实修复了无限递归,但由于某种原因,现在没有任何东西能够通过if语句,它将每个文件和目录视为其“..”或“.”将其更改为if(strcmp(WFD.cFileName,“..”)==0 | | strcmp(WFD.cFileName,“.”==0),这非常有效,不确定原因,但是谢谢。@user873294:它之所以有效,是因为strcmp不返回true/false,而是返回-1、0或1:1表示第二个字符串大于第一个字符串,0表示相等,而-1表示第一个字符串大于第二个字符串。这确实修复了无限递归,但由于某种原因,现在没有任何内容超过if语句,它将每个文件和目录视为其“..”或“.”将其更改为if(strcmp(WFD.cFileName,“..”)==0 | | | strcmp(WFD.cFileName,“.”“)==0),这非常有效,不知道为什么,但谢谢。@user873294:之所以有效,是因为
strcmp
不返回true/false,而是返回-1,0,或1:1表示第二个字符串大于第一个字符串,0表示相等,和-1表示第一个字符串大于第二个字符串。添加了此项,修复了堆栈溢出,但即使cFilename!=。。或它将继续,我已经在调试器中进行了逐步调试,不明白为什么它不会从这个if语句中排除真正的目录和文件。添加了这个,它修复了堆栈溢出,但即使cFilename!=。。或它将继续,我已经在调试程序中进行了逐步调试,但不明白为什么它不会从if语句中排除真实的目录和文件。