多个驱动器迭代期间的访问冲突
Access Violation during iteration of multiple drives
我在一个项目中工作,我必须循环访问作为输入的一组驱动器以列出其中存在的文件.我使用 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
跨多个线程。
相关文章:
- 使用迭代器时如何访问对象在向量中的位置?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 访问要输出的矢量迭代器元素
- 如何为我的容器实现随机访问迭代器?
- 在无法访问向量的情况下查找迭代器的末尾
- 对于C++随机访问迭代器(矢量迭代器),迭代器之间的差异是如何计算的?
- 对于随机访问迭代器(矢量迭代器),迭代器C++样式指针吗?
- 在迭代期间添加到 std::unordered_set(或 unordered_map)中的元素是否会在迭代期间访问?
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 封装 std::map 以允许迭代,但没有直接密钥访问?
- C++访问带有迭代器的向量的指针元素
- 启用 MSVC 调试迭代器时堆栈分配器访问冲突
- 如何在 c++ 中访问一对迭代器的开头
- C++迭代器"for loop"习惯用法,其步长> 1 并允许非随机访问反向迭代器
- 多个驱动器迭代期间的访问冲突
- 从 lambda 访问for_each迭代器
- C++地图访问和迭代所花费的时间
- 向量索引访问与迭代器访问的效率
- 处理vector迭代中的访问冲突异常
- 如何访问C++列表迭代器循环中的"previous"元素?