多个驱动器迭代期间的访问冲突

Access Violation during iteration of multiple drives

本文关键字:访问冲突 迭代 驱动器      更新时间:2023-10-16

我在一个项目中工作,我必须循环访问作为输入的一组驱动器以列出其中存在的文件.我使用 Windows 线程实现了它并将这组文件存储在矢量中。如果我将单个驱动器作为输入,它将正常工作。但是当尝试迭代多个驱动器时,它显示"ListTest.exe 中0x5efaad4a未处理的异常 (msvcp100d.dll): 0xC0000005:访问冲突读取位置0xdddddde1。我尝试调试程序,但错误出现在程序中的随机位置。我真的不知道我的程序中的错误到底在哪里,因为它非常适合单个驱动器。

多驱动器列表.h

#include <string>
#include <iostream>
#include <Windows.h>
#include <vector>


namespace DriveFiles
{
    struct List
    {
         //std::string *scr ;
         std::vector<std::string>files[10];
    };  
    class FileList
    {
        //static const int MAX_THREADS = 3 ;
    public:
        //static vector<std::string>fil;
        //struct List *list;
        static void ListFiles(std::string DriveId);
        static DWORD WINAPI ParThread(LPVOID s);
        static DWORD WINAPI Listing(LPVOID s);
        //static void display(std::vector<std::string>&files);
    };
} 

多驱动器列表.cpp

#include <iostream>
#include <Windows.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <deque>
#include <sstream>
#include <string>
#include "MultiDrive List.h"
using namespace std;
CRITICAL_SECTION QueueLock;
CRITICAL_SECTION StoreLock;
//CRITICAL_SECTION FileLock;
#define MAX_THREADS 2
HANDLE Child[MAX_THREADS];
deque<string>directories;
//vector<string>files;
int Files = 0;
struct DriveFiles::List *list = new struct DriveFiles::List();
namespace DriveFiles
{
        void FileList :: ListFiles(string DriveId)
        {   
            DWORD threadid; 
            vector<string> v; 
            string buf; 

            stringstream ss(DriveId); 
            //InitializeCriticalSection(&FileLock);
            InitializeCriticalSection(&QueueLock);
            InitializeCriticalSection(&StoreLock);
            cout << " List Will be in file form in few Sec " << endl;
            directories.clear();
            list->files[0].clear();
             while (ss >> buf)
                v.push_back(buf);
            HANDLE *Parent = new HANDLE[v.size()];
            string *scr;
            scr = new string[v.size()];
            //list->scr = new string[v.size()];
            for(int i=0; i<v.size(); i++)
            {
                scr[i]= v[i];
            }
            //cout << "no of drives "<<v.size();
            //list = HeapAlloc(GetProcessHeap(),0,sizeof(List));
            long t1 = GetTickCount();
            for(int i=0;i<v.size();i++)
            {
                 Parent[i] = CreateThread(NULL,0,ParThread,(LPVOID)scr[i].c_str(),0,&threadid);
            }
            WaitForMultipleObjects(v.size(),Parent,TRUE,INFINITE);
            //display();
            cout<< "Execution Time " <<GetTickCount()-t1;
            v.clear();
            //return files;
        }

        DWORD WINAPI FileList :: ParThread(LPVOID s)
        {
            DWORD threadid;
            WIN32_FIND_DATAA ffd;
            //cout << "in parent" <<endl;
             //struct List *x;
            char *drive =(char*)s;
            string path = drive;
            cout<<drive;
            //vector<string>fil;
            //list->files[0] = fil;
            string spec = path + "\" + "*";
            HANDLE hFind = FindFirstFileA(spec.c_str(), &ffd);
             if (INVALID_HANDLE_VALUE == hFind) 
             {
                     cout << "FindFirstFile error";
             }
                //cout<<"List of Folders in Drive"<<endl;
            do
            {
                 if(!strcmp(ffd.cFileName, "..") == 0 && !strcmp(ffd.cFileName, ".") == 0)
                {
                    if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
                    {   
                        EnterCriticalSection(&QueueLock);
                         directories.push_back( path + "\" + ffd.cFileName );
                         LeaveCriticalSection(&QueueLock);
                         //cout << ffd.cFileName <<endl;
                    }
                    else
                    {
                        EnterCriticalSection(&StoreLock);
                        list->files[0].push_back( path + "\" + ffd.cFileName );
                        Files++;
                        LeaveCriticalSection(&StoreLock);
                    }

                 }
            }while (FindNextFileA(hFind, &ffd) != 0);
            FindClose(hFind);
            /*fstream out;
            EnterCriticalSection(&FileLock);
            out.open("List.txt",ios_base::out | ios_base::app );
            vector<string>::iterator it = fil.begin();
            if(fil.size()!=0)
            do
            {
                //cout << "Writing to .txt File ";
                out<<*it<<endl;
                *it++;
            }while(it!=fil.end());
            out.close();
            fil.clear();
            LeaveCriticalSection(&FileLock);*/
            //DeleteCriticalSection(&QueueLock);
            //cout << endl<<list->files[0].size();
            cout << endl<<"No of Files "<<Files;
            for(int i=0;i<MAX_THREADS;i++)
            {
                 Child[i] = CreateThread(NULL,0,Listing,(LPVOID)&list->files[i],0,&threadid);
                 //cout<<endl<<list->files[i+1].size();
                 if( Child[i] == NULL )
                 {
                    printf("CreateThread error: %dn", GetLastError());
                     return 0;
                 }
            }
             WaitForMultipleObjects(MAX_THREADS,Child,TRUE,INFINITE);
             return 0;
        }
        DWORD WINAPI FileList :: Listing(LPVOID s)
        {
            deque<string>subdir;
            string path = " ";
            string spec = " ";
            string subpath = " ";
            int Files = 0;
            //vector<string>files;
            vector<string>*file;
            file = (vector<string>*)s;
            WIN32_FIND_DATAA ffd;
            //InitializeCriticalSection(&QueueLock);

            while(true)     
            {
                        EnterCriticalSection(&QueueLock);
                        if(directories.empty())
                        {
                            LeaveCriticalSection(&QueueLock);
                            //Sleep(500);
                            break;
                    }
                        else
                        {
                            path = directories.front();
                            directories.pop_front();
                            spec = path + "\" + "*";
                            LeaveCriticalSection(&QueueLock);
                            subdir.push_front(path);
                        }
                        while(!subdir.empty())
                        {
                            subpath = subdir.front();
                            spec = subpath + "\" + "*";
                            subdir.pop_front();
                            HANDLE hfind = FindFirstFileA(spec.c_str(),&ffd);
                            if(hfind == INVALID_HANDLE_VALUE)
                                    continue;
                            cout << subpath << endl;
                            do
                            {
                                if(strcmp(ffd.cFileName,".") && strcmp(ffd.cFileName,".."))
                                {
                                    if(ffd.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
                                    {
                                        //EnterCriticalSection(&QueueLock);
                                        subdir.push_front(subpath + "\" + ffd.cFileName);
                                        //LeaveCriticalSection(&QueueLock);
                                    }
                                    else
                                    {   
                                        //EnterCriticalSection(&StoreLock);
                                        file->push_back(subpath + "\" + ffd.cFileName);
                                        Files++;
                                        //LeaveCriticalSection(&StoreLock);
                                    }
                            }
                        }while(FindNextFileA(hfind,&ffd));
                        FindClose(hfind);
                        hfind = INVALID_HANDLE_VALUE;
                    }
            }
            //subdir.clear();
            //directories.clear();
            //cout <<endl<<file->size();
            cout<<" No of Files  "<<Files <<endl ;
            //display(files);
            //subdir.clear();
            //HeapFree(GetProcessHeap(), 0, list);
            return 0;
        }
}

测试列表.cpp

#include <iostream>
#include <string>
#include <fstream>
#include "MultiDrive List.h"
using namespace std;
using namespace DriveFiles;
int main()
{
    string drv;
    //vector<string>files;
    ofstream out;
    //List *list;
    cout << "n Enter the Id of Drives to list " <<endl;
    getline(cin,drv);
    FileList :: ListFiles(drv);
    extern struct DriveFiles::List *list;
    /*for(int i=0;i<3;i++)
        cout <<endl<< list->files[i].size();*/
    //cout<<"Listed";
    for(int i=0;i<3;i++)
    {
        //while(k< list->files[i].size())
        //{
        //cout <<endl<< list->files[i].size();
            out.open("Lists.txt",ios_base::out | ios_base::app );
            vector<string>::iterator it = list->files[i].begin();
            if(list->files[i].size()!=0)
            do
            {
                //cout << "Writing to .txt File ";
                out<<*it<<endl;
                *it++;
                //k++;
            }while(it!=list->files[i].end());
            out.close();
        //}
        //list->files[i].clear();
    }
    system("pause");
    return 0;
}

我的代码只要 MultiDrive List.h 和 MultiDriveListing.cpp 来自静态 .lib 库。TestList.cpp是访问库以获取输出并打印的程序。欢迎任何改进和帮助。

尽管您的代码存在几个问题(泄漏就是其中之一),但快速浏览一下让我怀疑您的迭代器在此代码块中的增量。请尝试以下更改:

do
{
    out<<*it<<endl;
    ++it;          // <----- this line changed
}while(it!=list->files[i].end());

我怀疑这是用

(char*)s


跨多个线程。