在 C++ 中使用 Win32 API 递归目录遍历期间堆栈溢出

发布于 2024-11-27 20:52:19 字数 1574 浏览 0 评论 0原文

我一直试图弄清楚为什么这会导致堆栈溢出几个小时,可能是我缺少的一些简单的东西,它之前一直在工作,直到我弄乱它以尝试清理它。无论如何,一些新的眼光将不胜感激。

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;
}

I've been trying to figure out why this is giving me a stack overflow for hours, probably something simple that I just am missing, it was working earlier until I messed with it to try to clean it up. Anyways some fresh eyes would be greatly appreciated.

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夕嗳→ 2024-12-04 20:52:19

我认为问题出在这里:

    if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
        FindNextFile(hSearch,&WFD);
    }

添加“继续”语句来解决问题。检查“.”和“..”很好。问题是如果它们相邻就会出现代码中断。

编辑: 具体来说,在此代码块中的 FindNextFile 后面添加“继续”。

I think the problem is here:

    if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
        FindNextFile(hSearch,&WFD);
    }

Add a "continue" statement to fix the issue. The check for "." and ".." is good. The problem is the code breaks if they are adjacent.

Edit: Specifically, add "continue" after FindNextFile in this code block.

混浊又暗下来 2024-12-04 20:52:19

在第一个循环中尝试此更改:

if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
    continue;
}

Try this change in the first loop:

if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
    continue;
}
记忆消瘦 2024-12-04 20:52:19

在您的特定情况下,您可能会通过意外地将本地目录包含在枚举中而获得无限递归,然后枚举将再次包含本地目录,等等。

但即使您解决了这个问题,您也会调用 scan 递归地,如果你不非常小心,并且很好地理解你的内存需求、堆栈限制等,这很容易导致你的堆栈崩溃。

如果解决了无限递归问题,但仍然出现堆栈溢出,常见的解决方案是实现自己的堆栈,而不是依赖于递归函数调用。

请参阅维基百科上的堆栈(数据结构)文章,了解有关如何操作的一些详细信息堆栈有效。

In your particular case, you are probably getting an infinite recursion by accidentally including the local directory in your enumeration, which will then include the local directory again, etc.

But even if you solve this, you are calling scan recursively, which can easily cause your stack to blow if you're not very careful, and understand your memory requirements, stack limits, etc, very well.

If you solve the infinite recursion problem, and still get a stack overflow, the common solution is to implement your own stack, rather than relying on recursive function calls.

See the Stack (data structure) article on wikipedia for some amount of detail on how the stack works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文