【问题标题】:Access Violation during iteration of multiple drives多个驱动器迭代期间的访问冲突
【发布时间】:2014-02-21 06:08:05
【问题描述】:

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

MultiDrive List.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);
    };
} 

MultiDriveListing.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: %d\n", 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;
        }
}

TestList.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 是访问该库以获取输出并打印它的程序。请提供任何改进和帮助欢迎。

【问题讨论】:

  • 我建议您进行一些调试是否容易?你知道怎么?我相信你真正的问题是你还没有学会如何去做。学会调试以后会更容易进步。
  • 我还要指出您的代码泄漏得相当严重。尝试让自己摆脱新的并使用标准容器。我不愿意深入挖掘,因为这里的代码太多了。不能砍吗?这也将有助于您的调试。
  • @DavidHeffernan..我调试了,所以只有我告诉我有这个问题。因为它在我的问题中随机显示错误,所以我无法找到错误发生的确切位置。请帮助我。跨度>

标签: c++ multithreading winapi vector


【解决方案1】:

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

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

【讨论】:

  • ...感谢指点。但实际上错误发生在执行 MultiDriveListing.cpp 期间。我不知道错误到底发生在哪里。
  • 谢谢..但是请帮助我更改其他问题,因为我不知道确切的错误发生在哪里。
  • @WarriorPrince 在你的问题中你说 “我不知道错误在哪里” 现在你说 “错误发生在执行 MultiDriveListing 期间。 cpp",您需要将您从调试中获得的所有信息提供给我们。就像 David Heffernan 说的,我也不愿意调试这么大的代码转储。
  • ..我不知道 MultiDriveListing.cpp 到底发生了什么错误..这就是我想说的
【解决方案2】:

我怀疑它的用法

(char*)s


跨多个线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多