Переполнение стека во время рекурсивного обхода каталога с использованием Win32 API в C ++ - PullRequest
0 голосов
/ 01 августа 2011

Я пытался выяснить, почему это приводит к переполнению стека в течение нескольких часов, возможно, чего-то простого, чего мне просто не хватает, он работал раньше, пока я не испортил его, чтобы попытаться очистить его.В любом случае, некоторые свежие глаза будут высоко оценены.

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

Ответы [ 3 ]

2 голосов
/ 01 августа 2011

Я думаю, что проблема здесь:

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

Добавьте оператор "continue", чтобы исправить проблему. Чек на "." и ".." это хорошо. Проблема в том, что разрывы кода, если они смежные.

Изменить: В частности, добавить "продолжить" после FindNextFile в этом блоке кода.

1 голос
/ 01 августа 2011

Попробуйте это изменение в первом цикле:

if(strcmp(WFD.cFileName,"..") || strcmp(WFD.cFileName,".")){
    continue;
}
0 голосов
/ 01 августа 2011

В вашем конкретном случае вы, вероятно, получаете бесконечную рекурсию, случайно включив в перечисление локальный каталог, который затем снова включит локальный каталог и т. Д.

Но даже если вы решите это, выВызываете scan рекурсивно, что может легко привести к перегрузке вашего стека, если вы не очень осторожны, и очень хорошо понимают ваши требования к памяти, ограничения стека и т. д.

Если вы решаете проблему бесконечной рекурсиии, все еще получая переполнение стека, обычное решение состоит в том, чтобы реализовать свой собственный стек, а не полагаться на рекурсивные вызовы функций.

См. статью Stack (структура данных) в Википедии для некоторыхколичество деталей о том, как работает стек.

...